我有一个产品清单。我想基于多个包含多个关键字的字符串对象来过滤列表。
我尝试了几个选项,如下所示:
List<Product> products = new List<Product>();
products.Add(new Product() { Id = 1, Title = "Dit is product 1", Genre = "genre 1, genre 2, genre 4", Artist = "artist 1, artist 3"});
products.Add(new Product() { Id = 2, Title = "Johan Bach", Genre = "genre 3, genre 4, genre 6", Artist = "artist 3, artist 4" });
products.Add(new Product() { Id = 3, Title = "Straus is klaus", Genre = "genre 8, genre 7", Artist = "artist 9" });
products.Add(new Product() { Id = 4, Title = "Sebastiaan buch", Genre = "genre 9, genre 2, genre 3", Artist = "artist 5, artist 6" });
products.Add(new Product() { Id = 5, Title = "Beethoven rocks", Genre = "genre 5, genre 8, genre 11", Artist = "artist 1, artist 8" });
string querystring = "dit buch beethove";
string genre = "";
string artist = "artist 9";
var keys = querystring.Split(' ');
Console.WriteLine("");
Console.WriteLine("optie 1:");
List<Product> result = products.FindAll(s =>
s.Title.ContainsAny(keys) ||
s.Genre.ContainsAny(genre.Split(',')) ||
s.Artist.ContainsAny(artist.Split(','))
);
foreach (var product in result)
{
Console.WriteLine(product.Title);
}
Console.WriteLine("");
Console.WriteLine("optie 2:");
List<Product> option2 = products;
if (querystring.Length > 0 && querystring.Split(' ').Any())
option2 = option2.Where(s => s.Title.ContainsAny(querystring.Split(' '))).ToList();
if (genre.Length > 0 && genre.Split(',').Any())
option2 = option2.Where(s => s.Genre.ContainsAny(genre.Split(','))).ToList();
if (artist.Length > 0 && artist.Split(',').Any())
option2 = option2.Where(s => s.Artist.ContainsAny(artist.Split(','))).ToList();
foreach (var product in option2)
{
Console.WriteLine(product.Title);
}
Console.WriteLine("");
Console.WriteLine("optie 3:");
List<Product> results = new List<Product>();
if (querystring.Length > 0 && querystring.Split(' ').Any())
{
results = results = products.FindAll(s => s.Title.ContainsAny(keys));
}
if (genre.Length > 0 && genre.Split(',').Any())
{
results = results.Union(products.FindAll(s => s.Genre.ContainsAny(genre.Split(',')))).ToList();
}
if (artist.Length > 0 && artist.Split(',').Any())
{
results = results.Union(products.FindAll(s => s.Artist.ContainsAny(artist.Split(',')))).ToList();
}
foreach (var product in results)
{
Console.WriteLine(product.Title);
}
Console.ReadLine();
预期的结果集是选项3的结果集:产品ID 1,3,4和5
有没有更好的方法来做我想做的事情?
答案 0 :(得分:0)
由于您拥有的linq语句最终会在每个项目中运行并在每个项目上调用ContainsAny,因此每个项目最终都会执行拆分功能。
但是,您可以使用let关键字让split函数调用一次。
以下是let关键字的链接。
http://msdn.microsoft.com/en-us/library/bb383976.aspx
此外,由于您在代码的底部使用了这些拆分函数,我建议您创建一个数组类型的变量,并在代码的顶部执行一次拆分,以便您的linq语句和底部部分不需要多次打电话。
如果选择此方法,则无需在linq中使用ley关键字。