以下搜索方法适用 ,最多两个条款。
如何将其设置为动态,以便能够处理任意数量的搜索字词?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TestContains82343
{
class Program
{
static void Main(string[] args)
{
List<string> tasks = new List<string>();
tasks.Add("Add contract to Customer.");
tasks.Add("New contract for customer.");
tasks.Add("Create new contract.");
tasks.Add("Go through the old contracts.");
tasks.Add("Attach files to customers.");
var filteredTasks = SearchListWithSearchPhrase(tasks, "contract customer");
filteredTasks.ForEach(t => Console.WriteLine(t));
Console.ReadLine();
}
public static List<string> SearchListWithSearchPhrase(List<string> tasks, string searchPhrase)
{
string[] parts = searchPhrase.Split(new char[] { ' ' });
List<string> searchTerms = new List<string>();
foreach (string part in parts)
{
searchTerms.Add(part.Trim());
}
switch (searchTerms.Count())
{
case 1:
return (from t in tasks
where t.ToUpper().Contains(searchTerms[0].ToUpper())
select t).ToList();
case 2:
return (from t in tasks
where t.ToUpper().Contains(searchTerms[0].ToUpper()) && t.ToUpper().Contains(searchTerms[1].ToUpper())
select t).ToList();
default:
return null;
}
}
}
}
答案 0 :(得分:5)
如何更换
switch (searchTerms.Count())
{
case 1:
return (from t in tasks
where t.ToUpper().Contains(searchTerms[0].ToUpper())
select t).ToList();
case 2:
return (from t in tasks
where t.ToUpper().Contains(searchTerms[0].ToUpper()) && t.ToUpper().Contains(searchTerms[1].ToUpper())
select t).ToList();
default:
return null;
}
通过
(from t in tasks
where searchTerms.All(term => t.ToUpper().Contains(term.ToUpper()))
select t).ToList();
答案 1 :(得分:3)
只需反复拨打Where
...我已经改变了searchTerms
的处理方式,以使其更加LINQ-y:)
public static List<string> SearchListWithSearchPhrase
(List<string> tasks, string searchPhrase)
{
IEnumerable<string> searchTerms = searchPhrase.Split(' ')
.Select(x => x.Trim());
IEnumerable<string> query = tasks;
foreach (string term in searchTerms)
{
// See edit below
String captured = term;
query = query.Where(t => t.ToUpper().Contains(captured));
}
return query.ToList();
}
您应该注意,默认情况下,ToUpper()
会对文化敏感 - 关于不区分大小写的匹配有各种警告:(有关详细信息,请查看this guidance on MSDN。我不确定对于不区分大小写的Contains
有多少支持:(
All
绝对是一个有用的LINQ运算符,可以了解...
以下是我写它的方式:
return tasks.Where(t => searchTerms.All(term => t.ToUpper().Contains(term)))
.ToList();
(当我将一个运算符应用于外部查询时,我通常不使用查询表达式。)
编辑:Aargh,我不敢相信我陷入了captured variable issue :(你需要创建foreach
循环变量的副本,否则闭包将始终引用“当前”变量的值...在ToList
执行时始终为 last 值:(
编辑:请注意,到目前为止,所有内容在多次上限每个任务方面都是低效的。这在现实中可能很好,但你可以通过使用这样的东西来避免它:
IEnumerable<string> query = tasks.Select
(t => new { Original = t, Upper = t.ToUpper });
return query.Where(task => searchTerms.All(term => task.Upper.Contains(term)))
.Select(task => task.Original)
.ToList();
答案 2 :(得分:1)
目前无法测试代码,但您可以执行与此类似的操作:
from t in tasks
let taskWords=t.ToUpper().Split(new char[] { ' ' });
where searchTerms.All(term => taskWords.Contains(term.ToUpper()))
select t
答案 3 :(得分:0)
用for循环替换switch语句:)
[TestMethod]
public void TestSearch()
{
List<string> tasks = new List<string>
{
"Add contract to Customer.",
"New contract for customer.",
"Create new contract.",
"Go through the old contracts.",
"Attach files to customers."
};
var filteredTasks = SearchListWithSearchPhrase(tasks, "contract customer new");
filteredTasks.ForEach(Console.WriteLine);
}
public static List<string> SearchListWithSearchPhrase(List<string> tasks, string searchPhrase)
{
var query = tasks.AsEnumerable();
foreach (var term in searchPhrase.Split(new[] { ' ' }))
{
string s = term.Trim();
query = query.Where(x => x.IndexOf(s, StringComparison.InvariantCultureIgnoreCase) != -1);
}
return query.ToList();
}
答案 4 :(得分:0)
为什么不在分割术语并将其保存到列表后使用foreach和AddRange()。
List<ItemsImLookingFor> items = new List<ItemsImLookingFor>();
// search for terms
foreach(string term in searchTerms)
{
// add users to list
items.AddRange(dbOrList(
item => item.Name.ToLower().Contains(str)).ToList()
);
}
应适用于任何数量的条款。