給予初始化IEnumerable
:如何有效地確定IEnumerable是否包含多個元素?
IEnumerable<T> enumerable;
我想確定它是否有一個以上的元素。我覺得最明顯的方式做到這一點是:
enumerable.Count() > 1
不過,我相信Count()
枚舉整個集合,這是不必要的這種使用情況。例如,如果集合包含非常大量的元素或從外部來源提供其數據,那麼在性能方面可能會非常浪費。
如何在不枚舉超過2個元素的情況下做到這一點?
給予初始化IEnumerable
:如何有效地確定IEnumerable是否包含多個元素?
IEnumerable<T> enumerable;
我想確定它是否有一個以上的元素。我覺得最明顯的方式做到這一點是:
enumerable.Count() > 1
不過,我相信Count()
枚舉整個集合,這是不必要的這種使用情況。例如,如果集合包含非常大量的元素或從外部來源提供其數據,那麼在性能方面可能會非常浪費。
如何在不枚舉超過2個元素的情況下做到這一點?
您可以通過合併在System.Linq的擴展方法測試這個在許多方面...兩個簡單的例子都低於:
bool twoOrMore = enumerable.Skip(1).Any();
bool twoOrMoreOther = enumerable.Take(2).Count() == 2;
我更喜歡,因爲一個共同的方式,第一個檢查Count() >= 1
是否與Any()
,因此我覺得它更具可讀性。
這並不總是有效的,如果這是你丟失了數據的數據流跳過和/或拿走。此外,如果每次對可枚舉進行操作時數據都在發生變化,這意味着您在完成此測試後對數據的評估可能會有所不同。 – devshorts
@devshorts但他只關心計數,而不是實際的數據。 –
@devshorts True。當然,如果需要,您可以將Take(2)結果保存爲變量,但這不是問題中的要求。 –
爲了好玩,調用Next()兩次,然後獲得另一個IEnumerable。
或者,爲此特定目標編寫一個小封裝類:EnumerablePrefetcher : IEnumerable<T>
嘗試在初始化時獲取指定數量的項目。 @卡梅倫-S的解決方案是簡單,但下面是更有效的
其IEnumerable<T> GetItems()
方法應採用屈服回報以這種方式
foreach (T item in prefetchedItems) // array of T, prefetched and decided if IEnumerable has at least n elements
{
yield return item;
}
foreach (T item in otherItems) // IEnumerable<T>
{
yield return item;
}
。我想出了這個基於Enumerable.Count()
的方法。 Skip()
將始終迭代並且不會短路,以獲得source
的計數爲ICollection
或ICollection<T>
類型。
/// <summary>
/// Returns true if source has at least <paramref name="count"/> elements efficiently.
/// </summary>
/// <remarks>Based on int Enumerable.Count() method.</remarks>
public static bool HasCountOfAtLeast<TSource>(this IEnumerable<TSource> source, int count)
{
source.ThrowIfArgumentNull("source");
var collection = source as ICollection<TSource>;
if (collection != null)
{
return collection.Count >= count;
}
var collection2 = source as ICollection;
if (collection2 != null)
{
return collection2.Count >= count;
}
int num = 0;
checked
{
using (var enumerator = source.GetEnumerator())
{
while (enumerator.MoveNext())
{
num++;
if (num >= count)
{
return true;
}
}
}
}
return false; // < count
}
如果你必須指望它,那麼做點什麼,你最好強迫它評估一個列表或其他集合。 – devshorts
@devshorts,通過*計數*,你的意思是*取決於它的工作*或*使用'Count()'方法*? – Sam
我的意思是,如果你需要找到它上面有多少個元素,那麼根據這個做一些事情,你可以評估它。 'Count'會評估一次,然後如果再次迭代,則必須重新評估一切。與其他'IEnumerable'方法相同,如'Take'或Skip'。這真的取決於數據是什麼。 – devshorts