[英]Linq equivalent for collection contains at least x items; like .Any() but instead .AtLeast(int)
[英]Equivalent of Linq's Any() function for when a collection has multiple items
在 C# 中,使用 Linq,如果我想檢查一個集合是否有任何元素,我可以這樣做:
someCollection.Any()
哪個更好
someCollection.Count() > 0
因為后者將計算集合中的所有項目,所以當我真的不在乎有多少項目時,我只想知道是否有任何項目。
檢查一個集合是否有多個項目是否有等價物? 就像是:
someCollection.Many()
而不是必須做
someCollection.Count() > 1
愚蠢的問題,我知道,從我的研究來看,它看起來並不存在。 但由於它是我經常使用的東西,我想我會與社區再次確認。
謝謝
根據我的評論:
首先,您應該檢查IEnumerable<T> source
是否實際上是IReadOnlyCollection<T>
或ICollection<T>
,因為它具有您可以使用的.Count
屬性 - 這比任何迭代都更可取。
假設您的IEnumerable<T>
沒有O(1)
.Count
屬性,如果您想查看是否至少有1 個元素(即“至少 2 個或更多”),請使用source.Take(2).Count() == 2
或source.Skip(1).Any()
。
像這樣:
public static Boolean Many<T>( this IEnumerable<T> source )
{
if( source is null ) throw new ArgumentNullException(nameof(source));
if( source is ICollection<T> col ) return col.Count >= 2;
else if( source is IReadOnlyCollection<T> roCol ) return roCol.Count >= 2;
return source.Take(2).Count() == 2;
}
如果您想提高效率,請進行手動迭代:
public static Boolean Many<T>( this IEnumerable<T> source )
{
if( source is null ) throw new ArgumentNullException(nameof(source));
if( source is ICollection<T> col ) return col.Count >= 2;
else if( source is IReadOnlyCollection<T> roCol ) return roCol.Count >= 2;
Int32 count = 0;
using( IEnumerator<T> iter = source.GetEnumerator() )
{
while( iter.MoveNext() && count < 2 )
{
count += 1;
}
}
return count == 2;
}
如果您想提高效率,請允許消費者提供非盒裝枚舉器(例如List<T>.Enumerator
):
public static Boolean Many<TEnumerable,TEnumerator,TElement>( /*this*/ TEnumerable source, Func<TEnumerable,TEnumerator> getEnumerator )
where TEnumerable : IEnumerable<TElement>
where TEnumerator : IEnumerator<TElement>
{
if( source is null ) throw new ArgumentNullException(nameof(source));
if( getEnumerator is null ) throw new ArgumentNullException(nameof(getEnumerator));
//
if ( source is ICollection<TElement> col ) return col .Count >= 2;
else if( source is IReadOnlyCollection<TElement> roCol ) return roCol.Count >= 2;
Int32 count = 0;
using( TEnumerator iter = getEnumerator( source ) )
{
while( iter.MoveNext() && count < 2 )
{
count += 1;
}
}
return count == 2;
}
像這樣使用:
List<String> listOfStrings = new List<String>() { ... };
if( listOfStrings.Many</*TEnumerable:*/ List<String>, /*TEnumerator:*/ List<String>.Enumerator, /*TElement:*/ String >( l => l.GetEnumerator() ) )
{
}
list.GetEnumerator()
部分是必需的,因為它是將基於struct
的枚舉器傳遞到通用代碼中而無需裝箱(至少,不是沒有反射)的唯一方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.