在C#中过滤集合
我正在寻找一种非常快速的方法来过滤C#中的集合。我目前正在使用通用的List <object>集合,但是如果它们的性能更好,则可以使用其他结构。
当前,我只是创建一个新的List <object>并循环遍历原始列表。如果过滤条件匹配,我将副本放入新列表中。
有一个更好的方法吗?有没有一种可以进行过滤的方法,因此不需要临时列表?
解决方案
回答
如果我们使用的是C3.0,则可以使用linq,效果更好,更优雅:
List<int> myList = GetListOfIntsFromSomewhere(); // This will filter out the list of ints that are > than 7, Where returns an // IEnumerable<T> so a call to ToList is required to convert back to a List<T>. List<int> filteredList = myList.Where( x => x > 7).ToList();
回答
列表具有FindAll方法,该方法将为我们进行过滤并返回列表的子集。
msdn在此处有一个很棒的代码示例:http://msdn.microsoft.com/zh-cn/library/aa701359(VS.80).aspx
编辑:在我对Linq和Where()方法有一个很好的了解之前,我写了这篇文章。如果我今天要写这个,我可能会使用Jorge上面提到的方法。但是,如果我们陷在.NET 2.0环境中,则FindAll方法仍然可以使用。
回答
为此,我们可以使用" List <>"类的RemoveAll方法以及自定义的" Predicate"类...但是所有要做的工作是清理代码...在后台进行相同的操作是的,但是是的,它就位了,因此我们也可以在临时列表中进行操作。
回答
我们可以使用IEnumerable消除临时列表的需要。
public IEnumerable<T> GetFilteredItems(IEnumerable<T> collection) { foreach (T item in collection) if (Matches<T>(item)) { yield return item; } }
其中Matches是过滤方法的名称。我们可以像这样使用:
IEnumerable<MyType> filteredItems = GetFilteredItems(myList); foreach (MyType item in filteredItems) { // do sth with your filtered items }
必要时,这将调用GetFilteredItems函数,在某些情况下,如果我们不使用过滤后的集合中的所有项目,则可能会获得一些良好的性能提升。
回答
我们可以使用List的FindAll方法,以提供委托进行筛选。不过,我同意@IainMH的观点,除非这是一个庞大的清单,否则不必担心太多。
回答
If you're using C# 3.0 you can use linq
或者,如果我们愿意,可以使用C3编译器提供的特殊查询语法:
var filteredList = from x in myList where x > 7 select x;
回答
这是使用三种不同方法进行列表过滤的代码块/示例,我将它们组合在一起以展示基于Lambda和LINQ的列表过滤。
#region List Filtering static void Main(string[] args) { ListFiltering(); Console.ReadLine(); } private static void ListFiltering() { var PersonList = new List<Person>(); PersonList.Add(new Person() { Age = 23, Name = "Jon", Gender = "M" }); //Non-Constructor Object Property Initialization PersonList.Add(new Person() { Age = 24, Name = "Hyman", 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
回答
与使用提供给Lists FindAll方法的谓词相比,使用Linq相对要慢得多。还必须注意Linq,因为在访问结果之前,列表枚举实际上不会执行。这可能意味着当我们认为自己已创建过滤列表时,其内容可能与实际阅读时的预期有所不同。