zoukankan      html  css  js  c++  java
  • Linq实践教程(1):一行代码实现DataTable全文搜索(Full Text Search)

    话说某项目需要在客户端执行全文搜索,包括多条件和部分匹配。开发一个新功能首先得google,像这样的代码外国同行早就给我们准备好了,没想到竟然落空。Google不成就只能开发了,我一看有个实习的小伙,那就你了,开发这个功能,顺便练习一下Linq。他写了半天代码也没写出来,只好写了个传统的代码交差(见后面)。于是我就写了下面的代码:

    public static List<DataRow> FullTextSearch(this DataTable dataTable, string[] keywords)

    {

    var q = dataTable.AsEnumerable().Where<DataRow>(row => keywords.All(keyword => row.ItemArray.Select(p => p.ToString()).Any<string>(s => s.Contains(keyword))));

    return q.ToList();

    }

    例如 下面是出生婴儿的DataTable

    序号

    姓名

    出生日期

    性别

    医院

    1

    李韦

    2012-07-10

    解放军总医院

    2

    云岚

    2012-07-10

    朝阳妇幼医院

    3

    周玲

    2012-07-10

    海淀医院

    4

    于晴

    2012-08-10

    北京军区总医院

    5

    王凌

    2012-09-10

    协和医院

    6

    张玉

    2012-10-10

    中日友好医院

    现在我们要搜索2012年出生北京军区医院姓 "于"的小朋友,那搜索的关键字可以是:2012 军区 于

    string[] keywords = new string[]{"2012", "军区", ""};

    dataTable.FullTextSearch(keywords);

    搜索的结果如下:

    4

    于晴

    2012-08-10

    北京军区总医院

    有了这个扩展方法,我们就可以搜索各种各样的DataTable了,能满足基本的需求了。但这一句代码对于Linq的新手来说,其实还是挺长的,跟下面几个方法有关:

    名称 说明 举例
    Where 基于谓词筛选值序列。 Where<DataRow>(row => ),从所有的记录里筛选满足All()条件的
    All 确定序列中的所有元素是否满足条件。 keywords.All(keyword => ),所有的关键字都要满足下面的条件
    Select 将序列中的每个元素投影到新表中。 row.ItemArray.Select(p => p.ToString()),把object[]转变为string[]
    Any 确定序列中的任何元素是否都满足条件。 Any<string>(s => s.Contains(keyword),string[]中的任何项包含关键字

    问题的关键在于All和Any,对于一条记录来说,所有的关键字是否包含在记录的任意项里了(条件)。总的来说,我们要从一个表里找出前面条件为真的记录。其实Linq也没有什么特别神奇的,只不过是把一些循环语句和条件语句封装成函数式。看习惯了有声明式编程的感觉,比命令式的风格更容易看懂,并且也更不容易出错。对比一下实习生写的代码:

    public static List<DataRow> FullTextSearch(this DataTable dataTable, string keywords)

    {

    List<DataRow> row = new List<DataRow>();

    DataTable dt = new DataTable();

    string[] keywordToArray = keywords.Split(' ');

    List<string> collectionID = new List<string>();

    for (int i = 0; i < dataTable.Rows.Count; i++)

    {

    DataRow dr = dataTable.Rows[i];

    int flag = 0;

    foreach (var key in keywordToArray)

    {

    for (int j = 0; j < dr.ItemArray.Length; j++)

    {

    if (dr[j].ToString().Contains(key))

    {

    flag = flag + 1;

    break;

    }

    }

    }

    if (flag == keywordToArray.Length)

    row.Add(dataTable.Rows[i]);

    }

    return row;

    }

  • 相关阅读:
    Educational Codeforces Round 83 --- F. AND Segments
    Educational Codeforces Round 83 --- G. Autocompletion
    SEERC 2019 A.Max or Min
    2019-2020 ICPC Southwestern European Regional Programming Contest(Gym 102501)
    Educational Codeforces Round 78 --- F. Cards
    今天我学习了一门全新的语言
    codeforces 1323D 题解(数学)
    Educational Codeforces Round 80 (Div. 2) 题解 1288A 1288B 1288C 1288D 1288E
    Educational Codeforces Round 81 (Div. 2) 题解 1295A 1295B 1295C 1295D 1295E 1295F
    Codeforces Round #617 (Div. 3) 题解 1296C 1296D 1296E 1296F
  • 原文地址:https://www.cnblogs.com/FreeWick/p/2753016.html
Copyright © 2011-2022 走看看