如何查找List <t>中符合多个条件</t>的所有项目

时间:2013-12-03 13:42:18

标签: c# linq list filter

我有一个产品清单。我想基于多个包含多个关键字的字符串对象来过滤列表。

我尝试了几个选项,如下所示:

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

有没有更好的方法来做我想做的事情?

1 个答案:

答案 0 :(得分:0)

由于您拥有的linq语句最终会在每个项目中运行并在每个项目上调用ContainsAny,因此每个项目最终都会执行拆分功能。

但是,您可以使用let关键字让split函数调用一次。

以下是let关键字的链接。

http://msdn.microsoft.com/en-us/library/bb383976.aspx

此外,由于您在代码的底部使用了这些拆分函数,我建议您创建一个数组类型的变量,并在代码的顶部执行一次拆分,以便您的linq语句和底部部分不需要多次打电话。

如果选择此方法,则无需在linq中使用ley关键字。