面试问题:.Any() 与 if (.Length > 0) 测试集合是否有元素

发布于 2024-09-04 04:11:39 字数 295 浏览 3 评论 0原文

在最近的一次采访中,我被问到 .Any().Length > 之间有什么区别。 0 是以及为什么我在测试集合是否有元素时会使用其中之一。

这让我有点困惑,因为它看起来有点明显,但感觉我可能错过了一些东西。

当您只需要知道集合有元素时,我建议您使用 .Length ;当您希望过滤结果时,我建议您使用 .Any()

据推测 .Any() 也会影响性能,因为它必须在内部执行循环/查询。

In a recent interview I was asked what the difference between .Any() and .Length > 0 was and why I would use either when testing to see if a collection had elements.

This threw me a little as it seems a little obvious but feel I may be missing something.

I suggested that you use .Length when you simply need to know that a collection has elements and .Any() when you wish to filter the results.

Presumably .Any() takes a performance hit too as it has to do a loop / query internally.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

奈何桥上唱咆哮 2024-09-11 04:11:39

Length 仅适用于某些集合类型,例如Array

Any 是一种扩展方法,可与任何实现 IEnumerable 的集合一起使用。

如果存在Length,那么您可以使用它,否则使用Any


大概 .Any() 也会影响性能,因为它必须在内部执行循环/查询。

Enumerable.Any 不循环。它获取一个迭代器并检查 MoveNext 是否返回 true。以下是来自 .NET Reflector 的源代码。

public static bool Any<TSource>(this IEnumerable<TSource> source)
{
    if (source == null)
    {
        throw Error.ArgumentNull("source");
    }
    using (IEnumerator<TSource> enumerator = source.GetEnumerator())
    {
        if (enumerator.MoveNext())
        {
            return true;
        }
    }
    return false;
}

Length only exists for some collection types such as Array.

Any is an extension method that can be used with any collection that implements IEnumerable<T>.

If Length is present then you can use it, otherwise use Any.


Presumably .Any() takes a performance hit too as it has to do a loop / query internally.

Enumerable.Any does not loop. It fetches an iterator and checks if MoveNext returns true. Here is the source code from .NET Reflector.

public static bool Any<TSource>(this IEnumerable<TSource> source)
{
    if (source == null)
    {
        throw Error.ArgumentNull("source");
    }
    using (IEnumerator<TSource> enumerator = source.GetEnumerator())
    {
        if (enumerator.MoveNext())
        {
            return true;
        }
    }
    return false;
}
捂风挽笑 2024-09-11 04:11:39

我猜面试官可能想问一下检查 Any()Count() > 0(与长度> 0相对)。

基本上,这就是交易。

Any() 将有效地尝试通过枚举单个项目来确定集合是否具有任何成员。 (使用 Func 检查给定标准存在重载,但我猜测面试官指的是 Any() 的版本不带任何参数。)这使得它的复杂度为 O(1)。

Count() 将检查 LengthCount 属性(来自 T[]首先是 ICollectionICollection)。这通常是 O(1)。但是,如果这不可用,它将通过枚举整个事物来计算集合中的项目。这将是 O(n)。

CountLength 属性(如果可用)很可能是 O(1),就像 Any() ,并且可能会表现得更好,因为它根本不需要枚举。但 Count() 扩展方法不能确保这一点。因此有时是 O(1),有时是 O(n)。

据推测,如果您正在处理一个不起眼的 IEnumerable 并且您不知道它是否实现 ICollection您就很可能使用 Any() 比使用 Count() > 更好。 0如果您的目的只是确保集合不为空

I'm guessing the interviewer may have meant to ask about checking Any() versus Count() > 0 (as opposed to Length > 0).

Basically, here's the deal.

Any() will effectively try to determine if a collection has any members by enumerating over a single item. (There is an overload to check for a given criterion using a Func<T, bool>, but I'm guessing the interviewer was referring to the version of Any() that takes no arguments.) This makes it O(1).

Count() will check for a Length or Count property (from a T[] or an ICollection or ICollection<T>) first. This would generally be O(1). If that isn't available, however, it will count the items in a collection by enumerating over the entire thing. This would be O(n).

A Count or Length property, if available, would most likely be O(1) just like Any(), and would probably perform better as it would require no enumerating at all. But the Count() extension method does not ensure this. Therefore it is sometimes O(1), sometimes O(n).

Presumably, if you're dealing with a nondescript IEnumerable<T> and you don't know whether it implements ICollection<T> or not, you are much better off using Any() than Count() > 0 if your intention is simply to ensure the collection is not empty.

甜心小果奶 2024-09-11 04:11:39

Length 是数组类型的属性,而 Any()Enumerable 的扩展方法。因此,只能在处理数组时使用 Length。使用更抽象类型 (IEnumerable) 时,可以使用 Any()。

Length is a property of array types, while Any() is an extension method of Enumerable. Therefore, you can use Length only when working with arrays. When working with more abstract types (IEnumerable<T>), you can use Any().

憧憬巴黎街头的黎明 2024-09-11 04:11:39

.长度...系统.Array
.Any ... IEnumerable(扩展方法)。

只要我能找到它,我更喜欢使用“长度”。无论如何,属性比任何方法调用都是轻量级的。

不过,“Any”的实现不会比下面提到的代码做更多的事情。

 private static bool Any<T>(this IEnumerable<T> items)
        {
            return items!=null && items.GetEnumerator().MoveNext();
        }

还,
更好的问题可能是“.Count”和“.Length”之间的差异,怎么说:)。

.Length... System.Array
.Any ... IEnumerable (extension method).

I would prefer using "length" whenever i can find it. Property is anyhow light-weight than any method call.

Though, implementation of "Any" won't be doing anything more than the below mentioned code.

 private static bool Any<T>(this IEnumerable<T> items)
        {
            return items!=null && items.GetEnumerator().MoveNext();
        }

Also,
A better question could have been a difference beterrn ".Count" and ".Length", what say :).

萧瑟寒风 2024-09-11 04:11:39

我认为这是一个更普遍的问题,即如果我们有两种表达某种东西的方式,我们应该选择什么。
在这种情况下,我建议这样说:“要具体”,引用 Peter Norvig 在他的书《PAIP》中的内容。“

具体”的意思是使用最能描述您正在做的事情的内容。
因此,您想说的是:

collection.isEmpty()

如果您没有这样的构造,我将选择社区使用的常见习语。
对我来说.Length> 0 不是最好的,因为它强制您可以调整对象的大小。
假设您实现无限列表。 .Lenght 显然行不通。

I think this is a more general question of what to choose if we have 2 way to express something.
In does situation I would suggest the statement: "Be specific" quote from Peter Norvig in his book PAIP

Be specific mean use what best describe what your are doing.
Thus what you want to say is something like:

collection.isEmpty()

If you don't have such construct I will choose the common idiom that the communities used.
For me .Length > 0 is not the best one since it impose that you can size the object.
Suppose your implement infinite list. .Lenght would obviously not work.

╄→承喏 2024-09-11 04:11:39

听起来与这个关于 .Count 和 .Any 之间的差异的 Stackoverflow 问题非常相似,用于检查结果是否存在: 检查 Linq-to-xml 中是否存在结果

在这种情况下,最好使用 Any then Count,因为 Count 将迭代一个 IEnumerable

Sounds quite similar to this Stackoverflow question about difference between .Count and .Any for checking for existence of a result: Check for Existence of a Result in Linq-to-xml

In that case it is better to use Any then Count, as Count will iterate all elements of an IEnumerable

谁的年少不轻狂 2024-09-11 04:11:39

我们知道.Length仅用于数组,.Any()用于IEnumerable的集合。

您可以将 .Count 替换为 .Length,并且在处理 IEnumberable 集合时也会遇到同样的问题

。.Any() 和 .Count 在开始枚举器之前都会执行空检查。因此,就性能而言,它们是相同的。

至于数组,假设我们有以下行:

int[] foo = new int[10];

Here foo.Length is 10。虽然这是正确的,但它可能不是您正在寻找的答案,因为我们还没有向数组添加任何内容。如果 foo 为 null 它将抛出异常。

We know that .Length is only used for Arrays and .Any() is used for collections of IEnumerable.

You can swap .Count for .Length and you have the same question for working with collections of IEnumberable

Both .Any() and .Count perform a null check before beginning an enumerator. So with regards to performance they are the same.

As for the array lets assume we have the following line:

int[] foo = new int[10];

Here foo.Length is 10. While this is correct it may not be the answer your looking for because we haven't added anything to the array yet. If foo is null it will throw an exception.

满地尘埃落定 2024-09-11 04:11:39

讨论什么。所有源代码均可用,因此您知道:
如果您使用具有 Length 或 Count 属性的实例,那么您的时间复杂度始终为 O(1)。该值是您的实例的成员,您可以直接与任何其他值进行比较。它只是两个值之间的比较操作。

扩展方法 Any() 总是首先创建一个新迭代器,并尝试获取第一个元素。它也是 O(1),但由于创建了一个新的迭代器,每次调用 Any() 时都会为此迭代器分配少量内存。迭代器使用的 MoveNext() 的实现内部有 2 个比较操作和一个基于索引的列表访问,因为 MoveNext 还保存成员内部迭代的当前值(请参阅 List 枚举器的实现)
这就是为什么您应该更喜欢使用属性 Count 或 Length(如果可以使用的话)。

What for an discussion. All source code is available and so you know that:
If you are using instances which have the property Length or Count then you have always O(1). The value is a member of your instance and you can directly compare against any other value. It is only a compare operation between two values.

The extension method Any(), creates always as first a new iterator and the tries to get the first element. It is also O(1), but because of creating a new iterator a small amount of memory is allocated for this iterator, each time you call Any(). Inside implementation of MoveNext() which is used by the iterator there are 2 compare operations and one index based access to the list, because MoveNext saves also the current value for the iteration inside a member (see implementation for enumerator of List)
And that's why you should prefer usage of the properties Count or Length if you can use it.

梦巷 2024-09-11 04:11:39

.Length 迭代集合并返回元素数量。复杂度为 O(n)

.Any 检查集合是否至少有一项。复杂度为O(1)

.Length iterates through the collection and returns the number of elements. Complexity is O(n)

.Any checks whether the collection has at least one item. Complexity is O(1).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文