当前位置:  开发笔记 > 编程语言 > 正文

在C#中过滤集合

如何解决《在C#中过滤集合》经验,为你挑选了4个好方法。

我正在寻找一种非常快速的方法来过滤C#中的集合.我目前正在使用通用的List 集合,但如果它们表现更好,我愿意使用其他结构.

目前,我只是创建一个新的List 并循环到原始列表.如果过滤条件匹配,我将副本放入新列表.

有一个更好的方法吗?有没有办法过滤到位,所以不需要临时列表?



1> Jorge Córdob..:

如果你正在使用C#3.0,你可以使用linq,更好的方式和更优雅的方式:

List myList = GetListOfIntsFromSomewhere();

// This will filter out the list of ints that are > than 7, Where returns an
// IEnumerable so a call to ToList is required to convert back to a List.
List filteredList = myList.Where( x => x > 7).ToList();

如果找不到.Where,则意味着您需要using System.Linq;在文件顶部导入.


Where扩展方法返回IEnumerable ,而不是List .它应该是:myList.Where(x => x> 7).ToList()
@JonathanO您可以使用Func内部的方法.listOfStrings.Where(s => s.StartsWith("ch")).ToList();
@AlmightyR:只需将其定义为采用一个参数的方法即可。例如:`public bool预定义查询(int x){return x> 7; }`。然后您的`.Where(predefinedQuery)`可以正常工作。

2> Jon Erickson..:

下面是使用三种不同方法进行列表过滤的代码块/示例,我将它们放在一起以显示Lambdas和基于LINQ的列表过滤.

#region List Filtering

static void Main(string[] args)
{
    ListFiltering();
    Console.ReadLine();
}

private static void ListFiltering()
{
    var PersonList = new List();

    PersonList.Add(new Person() { Age = 23, Name = "Jon", Gender = "M" }); //Non-Constructor Object Property Initialization
    PersonList.Add(new Person() { Age = 24, Name = "Jack", Gender = "M" });
    PersonList.Add(new Person() { Age = 29, Name = "Billy", Gender = "M" });

    PersonList.Add(new Person() { Age = 33, Name = "Bob", Gender = "M" });
    PersonList.Add(new Person() { Age = 45, Name = "Frank", Gender = "M" });

    PersonList.Add(new Person() { Age = 24, Name = "Anna", Gender = "F" });
    PersonList.Add(new Person() { Age = 29, Name = "Sue", Gender = "F" });
    PersonList.Add(new Person() { Age = 35, Name = "Sally", Gender = "F" });
    PersonList.Add(new Person() { Age = 36, Name = "Jane", Gender = "F" });
    PersonList.Add(new Person() { Age = 42, Name = "Jill", Gender = "F" });

    //Logic: Show me all males that are less than 30 years old.

    Console.WriteLine("");
    //Iterative Method
    Console.WriteLine("List Filter Normal Way:");
    foreach (var p in PersonList)
        if (p.Gender == "M" && p.Age < 30)
            Console.WriteLine(p.Name + " is " + p.Age);

    Console.WriteLine("");
    //Lambda Filter Method
    Console.WriteLine("List Filter Lambda Way");
    foreach (var p in PersonList.Where(p => (p.Gender == "M" && p.Age < 30))) //.Where is an extension method
        Console.WriteLine(p.Name + " is " + p.Age);

    Console.WriteLine("");
    //LINQ Query Method
    Console.WriteLine("List Filter LINQ Way:");
    foreach (var v in from p in PersonList
                      where p.Gender == "M" && p.Age < 30
                      select new { p.Name, p.Age })
        Console.WriteLine(v.Name + " is " + v.Age);
}

private class Person
{
    public Person() { }
    public int Age { get; set; }
    public string Name { get; set; }
    public string Gender { get; set; }
}

#endregion



3> Mykroft..:

List具有FindAll方法,它将为您进行过滤并返回列表的子集.

msdn在这里有一个很好的代码示例:http://msdn.microsoft.com/en-us/library/aa701359(VS.80).aspx

编辑:在我对Linq和Where()方法有很好的理解之前,我写过这篇文章.如果我今天写这个,我可能会使用Jorge提到的方法.如果您陷入.NET 2.0环境,FindAll方法仍然有效.


Linq很好,但至少慢了一个量级,所以FindAll和过滤扩展方法(例如,数组中有一堆)不依赖于IEnumerable,对性能很重要的场景仍然有意义.(FWIW,我得到的结果是因为Linq和/或IEnumerable需要7到50倍的时间)

4> Serhat Ozgel..:

您可以使用IEnumerable来消除临时列表的需要.

public IEnumerable GetFilteredItems(IEnumerable collection)
{
    foreach (T item in collection)
    if (Matches(item))
    {
        yield return item;
    }
}

其中Matches是过滤方法的名称.你可以这样使用:

IEnumerable filteredItems = GetFilteredItems(myList);
foreach (MyType item in filteredItems)
{
    // do sth with your filtered items
}

这将在需要时调用GetFilteredItems函数,并且在某些情况下,您不使用过滤集合中的所有项目,它可以提供一些良好的性能增益.

推荐阅读
U友50081205_653
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有