从集合中查找一定数量的值

时间:2012-10-04 08:22:48

标签: c# linq

我有一些代码根据过滤器值过滤排序对象的集合。例如,我想找到Name=="searchquery"的对象。然后我想从该集合中获取前X个值。

我的问题:

  • 我的收藏是List<T>。此集合是否保证排序顺序?

  • 如果是这样,是否有内置的方法来查找满足条件的前X个对象?我正在寻找像

    这样的东西
    collection.FindAll(o=>o.Name=="searchquery",100);
    

    这会给我满足条件的前100个对象。原因是性能,一旦我找到了100个对象,我不想继续检查整个集合。

  • 如果我写:

    collection.FindAll(o=>o.Name=="searchquery").Take(100);
    

    运行时是否足够智能,一旦达到100就停止检查?

我当然可以自己实现,但如果有内置方式(比如LInQ方法),我宁愿使用它。

4 个答案:

答案 0 :(得分:4)

collection.Where(o=>o.Name=="searchquery").Take(100)

顺序应与原始列表的顺序相同,一旦需要100个元素,它将停止检查(Where返回枚举,该枚举仅在您获取元素时进行评估)。来自the documentation

  

此方法通过使用延迟执行来实现。立即返回值是一个对象,它存储执行操作所需的所有信息。在通过直接调用其GetEnumerator方法或在Visual C#中使用foreach或在Visual Basic中使用For Each来枚举对象之前,不会执行此方法表示的查询。

如果您需要不同的排序顺序,则必须指定它(这当然意味着您别无选择,只能检查所有元素)。

答案 1 :(得分:1)

确定,

我的收藏是List<T>。此集合是否保证排序顺序?

不,但它会保留插入顺序。

如果是这样,是否有内置的方法来查找满足条件的前X个对象?

     someEnumerable.Where(r => r.Name == "searchquery").Take(100)

如果我写:

    // Some linq that works

运行时是否足够聪明,一旦达到100就停止检查?

是的,可能是


现在,如果您已经排序了IList,并且想要快速迭代前100个项目,请执行此操作。

var list = sourceEnumerable.OrderBy(r => r.Name).ToList();
foreach(var r in list.Where(r => r.Name == "searchquery").Take(100))
{
    // Do something
}

答案 2 :(得分:1)

 collection.Where(o=>o.Name=="searchquery").Take(100)

是最正确的答案,因为在幕后Where延迟执行,下面是Where方法的实现方式:

Where(this IEnumerable<T>, Func<T, bool> func)
{
    foreach (var item in collection)
    {
        if (func(item))
        {
            yield return item;
        }
    }
}

因此,当调用Take(100)时,循环只会找到满足条件的前100个项目。

答案 3 :(得分:1)

如果您确定不会重复集合中的对象(例如主键),则可以使用SortedList而不是List<T>。这将保证,当您使用特定条件过滤列表时,您的列表将被排序。看一下排序列表示例:

http://msdn.microsoft.com/en-us/library/system.collections.sortedlist(v=vs.100).aspx