如何确保序列具有一定的长度?
我想检查 IEnumerable
是否包含恰好一个元素。此代码片段确实有效:
bool hasOneElement = seq.Count() == 1
但是它的效率不是很高,因为 Count()
将枚举整个列表。显然,知道列表为空或包含超过 1 个元素意味着它不为空。是否有具有这种短路行为的扩展方法?
I want to check that an IEnumerable
contains exactly one element. This snippet does work:
bool hasOneElement = seq.Count() == 1
However it's not very efficient, as Count()
will enumerate the entire list. Obviously, knowing a list is empty or contains more than 1 element means it's not empty. Is there an extension method that has this short-circuiting behaviour?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这应该可以做到:
您可以进一步省略它,但我不建议您这样做:
这是一种很时髦的技巧,但可能不应该在生产代码中使用。只是还不够清楚。事实上,&& 的 LHS 中的副作用是RHS 正常工作所需的运算符只是令人讨厌......同时很有趣;)
编辑:我刚刚看到你想出了完全相同的东西,但长度是任意的。不过,您的最终返回语句是错误的 - 它应该是 return
!en.MoveNext()
。这是一个完整的方法,具有更好的名称(IMO),参数检查和优化ICollection
/ICollection
:编辑:现在对于函数式粉丝来说,递归形式
CountEquals
(请不要使用这个,它只是为了咯咯笑):编辑:请注意,对于像 LINQ to SQL 这样的东西,您应该使用简单的
Count ()
方法 - 因为这将允许它在数据库中完成,而不是在获取实际结果之后完成。This should do it:
You could elide this further, but I don't suggest you do so:
It's the sort of trick which is funky, but probably shouldn't be used in production code. It's just not clear enough. The fact that the side-effect in the LHS of the && operator is required for the RHS to work appropriately is just nasty... while a lot of fun ;)
EDIT: I've just seen that you came up with exactly the same thing but for an arbitrary length. Your final return statement is wrong though - it should be return
!en.MoveNext()
. Here's a complete method with a nicer name (IMO), argument checking and optimization forICollection
/ICollection<T>
:EDIT: And now for functional fans, a recursive form of
CountEquals
(please don't use this, it's only here for giggles):EDIT: Note that for something like LINQ to SQL, you should use the simple
Count()
approach - because that'll allow it to be done at the database instead of after fetching actual results.不,但您可以自己写一个:
编辑:澄清后从至少更改为完全。
对于更通用和更有效的解决方案(仅使用 1 个枚举器并检查序列是否实现了
ICollection
或ICollection
在这种情况下不需要枚举),您可能想看看我的答案此处,可让您指定是否要查找Exact
、AtLeast
或AtMost
测试。No, but you can write one yourself:
EDIT: Changed from atleast to exactly after clarification.
For a more general and efficient solution (which uses only 1 enumerator and checks if the sequence implements
ICollection
orICollection<T>
in which case enumeration is not necessary), you might want to take a look at my answer here, which lets you specify whether you are looking forExact
,AtLeast
, orAtMost
tests.seq.Skip(1).Any()
将告诉您列表是否有零个或一个元素。我认为您所做的编辑是检查长度 n 的最有效方法。但有一个逻辑错误,小于 length 的项将返回 true。看看我对第二个 return 语句做了什么。
seq.Skip(1).Any()
will tell you if the list has zero or one elements.I think the edit you made is about the most efficient way to check the length is n. But there's a logic fault, items less than length long will return true. See what I've done to the second return statement.
这个怎么样?
Take()
将确保我们调用MoveNext
的次数不会超过count+1
次。我想指出的是,对于
ICollection
的任何实例,原始实现source.Count() == count
应该更快,因为Count() 已优化为仅查看
Count
成员。How about this?
The
Take()
will make sure we never callMoveNext
more thancount+1
times.I'd like to note that for any instance of
ICollection
, the original implementationsource.Count() == count
should be faster becauseCount()
is optimised to just look at theCount
member.我相信您正在寻找的是
.Single()
。除 1 之外的任何其他情况都会引发您可以捕获的 InvalidOperationException。http://msdn.microsoft.com/nb-no/library/bb155325.aspx
I believe what you're looking for is
.Single()
. Anything other than exactly one will throw InvalidOperationException that you can catch.http://msdn.microsoft.com/nb-no/library/bb155325.aspx