面试问题:.Any() 与 if (.Length > 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
Length
仅适用于某些集合类型,例如Array
。Any
是一种扩展方法,可与任何实现IEnumerable
的集合一起使用。如果存在
Length
,那么您可以使用它,否则使用Any
。Enumerable.Any
不循环。它获取一个迭代器并检查MoveNext
是否返回 true。以下是来自 .NET Reflector 的源代码。Length
only exists for some collection types such asArray
.Any
is an extension method that can be used with any collection that implementsIEnumerable<T>
.If
Length
is present then you can use it, otherwise useAny
.Enumerable.Any
does not loop. It fetches an iterator and checks ifMoveNext
returns true. Here is the source code from .NET Reflector.我猜面试官可能想问一下检查
Any()
与Count() > 0
(与长度> 0
相对)。基本上,这就是交易。
Any()
将有效地尝试通过枚举单个项目来确定集合是否具有任何成员。 (使用Func
检查给定标准存在重载,但我猜测面试官指的是Any()
的版本不带任何参数。)这使得它的复杂度为 O(1)。Count()
将检查Length
或Count
属性(来自T[]
或首先是 ICollection
或ICollection
)。这通常是 O(1)。但是,如果这不可用,它将通过枚举整个事物来计算集合中的项目。这将是 O(n)。Count
或Length
属性(如果可用)很可能是 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()
versusCount() > 0
(as opposed toLength > 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 aFunc<T, bool>
, but I'm guessing the interviewer was referring to the version ofAny()
that takes no arguments.) This makes it O(1).Count()
will check for aLength
orCount
property (from aT[]
or anICollection
orICollection<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
orLength
property, if available, would most likely be O(1) just likeAny()
, and would probably perform better as it would require no enumerating at all. But theCount()
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 implementsICollection<T>
or not, you are much better off usingAny()
thanCount() > 0
if your intention is simply to ensure the collection is not empty.Length
是数组类型的属性,而Any()
是Enumerable
的扩展方法。因此,只能在处理数组时使用 Length。使用更抽象类型 (IEnumerable
) 时,可以使用 Any()。Length
is a property of array types, whileAny()
is an extension method ofEnumerable
. Therefore, you can use Length only when working with arrays. When working with more abstract types (IEnumerable<T>
), you can use Any()..长度...系统.Array
.Any ... IEnumerable(扩展方法)。
只要我能找到它,我更喜欢使用“长度”。无论如何,属性比任何方法调用都是轻量级的。
不过,“Any”的实现不会比下面提到的代码做更多的事情。
还,
更好的问题可能是“.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.
Also,
A better question could have been a difference beterrn ".Count" and ".Length", what say :).
我认为这是一个更普遍的问题,即如果我们有两种表达某种东西的方式,我们应该选择什么。
在这种情况下,我建议这样说:“要具体”,引用 Peter Norvig 在他的书《PAIP》中的内容。“
具体”的意思是使用最能描述您正在做的事情的内容。
因此,您想说的是:
如果您没有这样的构造,我将选择社区使用的常见习语。
对我来说
.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:
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.听起来与这个关于 .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
我们知道.Length仅用于数组,.Any()用于IEnumerable的集合。
您可以将 .Count 替换为 .Length,并且在处理 IEnumberable 集合时也会遇到同样的问题
。.Any() 和 .Count 在开始枚举器之前都会执行空检查。因此,就性能而言,它们是相同的。
至于数组,假设我们有以下行:
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:
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.
讨论什么。所有源代码均可用,因此您知道:
如果您使用具有 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.
.Length
迭代集合并返回元素数量。复杂度为O(n)
.Any
检查集合是否至少有一项。复杂度为O(1)
。.Length
iterates through the collection and returns the number of elements. Complexity isO(n)
.Any
checks whether the collection has at least one item. Complexity isO(1)
.