3

我有一些代码可以根据过滤器值过滤排序对象的集合。例如,我想找到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

4 回答 4

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

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

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

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

于 2012-10-04T08:24:43.537 回答
1

如果您确定您的集合中的对象不重复(例如主键),那么您可以使用 SortedList 而不是List<T>. 这将保证,当您使用特定标准过滤列表时,您的列表将被排序。在这里查看排序列表示例:

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

于 2012-10-04T10:55:54.140 回答
1
 collection.Where(o=>o.Name=="searchquery").Take(100)

是最正确的答案,因为幕后Wheredeferred execution,下面是Where方法是如何实现的:

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

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

于 2012-10-04T09:09:47.837 回答
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
}
于 2012-10-04T08:39:36.037 回答