【发布时间】:2008-12-16 21:30:48
【问题描述】:
我正在运行 C# 框架 2.0,我想从列表中获取一些数据?该列表是一个列表。如果不对 List 的每个元素进行手动循环和比较,我该如何做到这一点?
【问题讨论】:
我正在运行 C# 框架 2.0,我想从列表中获取一些数据?该列表是一个列表。如果不对 List 的每个元素进行手动循环和比较,我该如何做到这一点?
【问题讨论】:
如果我正确地回答了您的问题,您只需调用 Find() 或 FindAll() 方法即可将数据项从列表中取出。例如:
List<string> myList = ..;
List<string> startingWithA = myList.FindAll(delegate(string s) { return s.StartsWith("A"); });
【讨论】:
你可以试试谓词。这是我为说明这一点而编写的代码。当然,正如您在此示例中所见,您可以将 Predicate 移到调用类之外并对其进行控制。如果您需要更多选择,这很有用。在谓词中,您可以与对象的所有属性/功能进行许多比较。
static void Main()
{
List<SimpleObject> list = new List<SimpleObject>();
list.Add(new SimpleObject(1,"Jon"));
list.Add(new SimpleObject( 2, "Mr Skeet" ));
list.Add(new SimpleObject( 3,"Miss Skeet" ));
Predicate<SimpleObject> yourFilterCriteria = delegate(SimpleObject simpleObject)
{
return simpleObject.Name.Contains("Skeet");
};
list = list.FindAll(yourFilterCriteria);//Get only name that has Skeet : Here is the magic
foreach (SimpleObject o in list)
{
Console.WriteLine(o);
}
Console.Read();
}
public class SimpleObject
{
public int Id;
public string Name;
public SimpleObject(int id, string name)
{
this.Id=id;
this.Name=name;
}
public override string ToString()
{
return string.Format("{0} : {1}",Id, Name);
}
}
【讨论】:
如果没有 LINQ,您的主要选择是对列表的每个元素进行循环和比较。不过,有一些方法可能会对您有所帮助。
List<T>.FindAll() 接受Predicate 委托,并将返回所有符合条件的项目。 List<T>.CopyTo() 和 List<T>.GetRange() 让您可以提取一系列元素。除此之外,您在 LINQ 之外的特定选择方面确实无能为力。
【讨论】:
事实是,即使您最终通过 Find 或 FindAll 使用谓词,它在内部所做的只是循环遍历列表,并运行您的谓词以测试匹配项。就性能而言,您不会获得任何好处,但它肯定会使代码更整洁。
【讨论】:
不幸的是,List 数据结构需要迭代来查找数据(请注意,上面的 FindAll 方法将在后台迭代您的集合 - 以防万一您不惜一切代价试图避免这种情况),除非您知道该数据的索引那么你可以这样做:
List<String> list = new List<String>();
list.Add("andrew");
list.Add("nicole");
String value = list[1]; // returns "nicole"
【讨论】:
我认为上面的大多数答案都只是提供替代方法来做你想要避免的事情。给定数据结构,无论您选择哪种实现,您/它都必须比较每个项目并挑选出匹配的项目。
根据您的匹配条件,SortedList 可以帮助您避免为每个查询搜索整个列表。如果您的列表包含您创建的对象,覆盖 GetHashCode 和 Equals 将帮助您。
如果您的匹配条件相当复杂,您可能需要完全不同的数据结构,例如用于字符串的trie。
【讨论】: