获取与单词列表匹配的字符串的子列表

时间:2015-06-03 14:37:55

标签: c# linq predicate

List<string> myList = new List<string>() 
 { 
      "This is a first matching exemple", 
      "This is second matching exemple", 
      "this one don't match", 
      "Here, the last item" 
 };

 List<string> words = new List<string>() { "This", "is" };

如何获得与所有单词匹配的列表

List<string> result = myList.Contains(AllWords???);

编辑1:我忘记指定单词不必完全匹配。

因此:

 List<string> words = new List<string>() { "This", "i" }
例如

必须返回相同的结果。

编辑2:在阅读了一些答案(chomba代码示例)之后,我将我的代码更新为:

List<string> _list = new List<string>();
// Populated from factory.
_list = SQLFactory  .GetDataView("Provider")
                    .ToTable()
                    .AsEnumerable()
                    .Select(r => r[1].ToString())
                    .ToList<string>();

// Construct list of word from textbox.
List<string> words = txtName.Text.ToLower().Split(' ').ToList();

// Update ListView
ListView.ListViewItemCollection lvic = new ListView.ListViewItemCollection(lvName);
lvName.BeginUpdate();
lvName.Items.Clear();
lvic.AddRange(_list .AsParallel()
                    .Where(x => words.All(word => x.Contains(word)))
                        .AsParallel()
                        .Select(t => new ListViewItem(t))
                        .ToList()
                        .ToArray());
lvName.EndUpdate();

但结果列表视图仍然遗漏了一些项目。 First search

Second search

编辑3:问题解决了。我只需管理单词的情况。

lvic.AddRange(_list .AsParallel()
                    .Where(x => words.All(word => x.Contains(word)))
                        .AsParallel()
                        .Select(t => new ListViewItem(t))
                        .ToList()
                        .ToArray());

4 个答案:

答案 0 :(得分:1)

可能有一种更有效的方法可以做到这一点,但现在想到这一点:

 var result = (from sentence in myList let wordsArray = sentence.Split(' ').ToList() 
               where wordsArray.Intersect(words).Count() == words.Count 
               select sentence).ToList();

答案 1 :(得分:0)

这应该有效:

List<string> result = myList.Where(x => !words.Except(x.Split(' ')).Any()).ToList();

或者如果您不需要完全匹配的话:

List<string> result = myList.Where(x => words.All(word => x.Contains(word))).ToList();

答案 2 :(得分:0)

List<String> myList = new ArrayList<String>(); 

    myList.add("This is a first matching exemple"); 
    myList.add("This is second matching exemple"); 
            myList.add( "this one don't match"); 
                    myList.add("Here, the last item"); 


         List<String> words = new ArrayList<String>();
         words.add("This");
         words.add("is");
         List<String> newList = new ArrayList<String>();
String text = words.get(0)+" "+words.get(1);
Iterator it = myList.iterator();
Iterator it1 = words.iterator();

while(it.hasNext()){
String x =  (String) it.next();
if(x.contains(text)){
    newList.add(x);
}

}
System.out.println(newList);

答案 3 :(得分:0)

这是最终的解决方案。我已经添加了一些并行语法来加速执行。

lvName是一个列表视图。

txtName是一个文本框,用于查找匹配的单词(与空格分开)。

使用至少拥有2列的查询初始化DataView _view。第2列是我们要搜索的字符串。

DataView _view = GettingDataFromFunctionCall();
List<string> _list = new List<string>();
// Populated from factory.
_list = _view.ToTable()
             .AsEnumerable()
             .Select(row => row[1].ToString())
             .ToList<string>();

// Construct list of word from textbox.
List<string> words = txtName.Text.ToLower().Split(' ').ToList();

// Update ListView
ListView.ListViewItemCollection lvic = new ListView.ListViewItemCollection(lvName);
lvName.BeginUpdate();
lvName.Items.Clear();
lvic.AddRange(_list .AsParallel()
                .Where(x => words.All(word => x.ToLower().Contains(word)))
                    .AsParallel()
                    .Select(t => new ListViewItem(t))
                    .ToList()
                    .ToArray());
lvName.EndUpdate();