关于C#:确定集合的有效方法至少有2个项

Efficient way to determine collection has at least 2 items

我知道Linq提供了确定集合是否包含任何项的功能。如

1
var anyCategories= categories.Any();

这是非常有效的,因为如果它找到了至少一个项目,那么迭代就停止了。现在,如果我想知道一个集合是否至少有两个项呢?这是我目前拥有的代码:

1
var atLeastTwoCategories= categories.Count() > 1;

如果计数大于1,则此项将遍历整个集合。我认为这是非常低效的。Linq或.NET是否提供了一种更好的方法?


最简单的方法是:

1
var atLeastTwoCategories= categories.Skip(1).Any();

我假设"collection"实际上是指linq支持的任何IEnumerable,比如说,一个SQL数据源。对于ListArray,.net可以优化倒计时到O(1)操作,因此没有区别。请参阅https://stackoverflow.com/a/981283/224370,但对于来自数据库的"集合"或在元素上迭代成本较高的地方,这种方法更快。


不要使用方法count(),使用属性count!(拆下支架)

这应该只返回数组的长度,而不尝试任何过滤逻辑。


要实现如果集合包含n或更多项时返回true的AtLeast(n)操作,您需要迭代集合n - 1次,然后检查是否还有更多项剩余。或者用代码表示:

1
2
3
4
5
6
7
8
public static bool AtLeast<T>(this IEnumerable<T> collection, int n)
{
    if (n < 1)
        return true; // or exception, you choose
    if (n == 1)
        return collection.Any();
    return collection.Skip(n - 1).Any();
}

这不需要对集合进行完整的迭代,因此应该是相当有效的。

您可以尝试通过为ArrayList和任何其他您能想到更好的方法的类型添加特定版本来提高效率。例如:

1
2
3
4
public static bool AtLeast<T>(this Array<T> array, int n)
{
    return array.Length >= n;
}