[英]Faking IGrouping for LINQ
想象一下,您有一個大型數據集,可能會或可能不會被數據集元素的特定條件過濾,這些條件可以進行密集計算。 在未過濾的情況下,元素按該條件的值分組 - 條件計算一次。
但是,在進行過濾的情況下,盡管后續代碼仍然希望看到IEnumerable<IGrouping<TKey, TElement>>
集合,但執行導致條件為的條件的GroupBy
操作沒有意義。為每個元素重新評估第二次。 相反,我希望能夠通過適當地包裝過濾結果來創建IEnumerable<IGrouping<TKey, TElement>>
,從而避免對條件進行另一次評估。
除了實現我自己的提供IGrouping
接口的類之外,還有其他方法可以實現這種優化嗎? 是否存在支持這種情況的LINQ方法,它將為我提供IEnumerable<IGrouping<TKey, TElement>>
結果? 還有另外一種我沒有考慮過的方法嗎?
條件計算一次
我希望那些鑰匙還在某個地方......
如果你的數據是這樣的結構:
public class CustomGroup<T, U>
{
T Key {get;set;}
IEnumerable<U> GroupMembers {get;set}
}
您可以使用如下查詢來投影此類項目:
var result = customGroups
.SelectMany(cg => cg.GroupMembers, (cg, z) => new {Key = cg.Key, Value = z})
.GroupBy(x => x.Key, x => x.Value)
受David B的回答啟發,我想出了一個簡單的解決方案。 這么簡單,我不知道我是怎么錯過它的。
為了執行過濾,我顯然需要知道我過濾的條件的值。 因此,給定條件c
,我可以將過濾后的列表投影為:
filteredList.GroupBy(x => c)
這樣可以避免在元素上重新計算屬性(由x
表示)。
我意識到的另一個解決方案是在執行過濾之前反轉查詢的順序並執行分組。 這也意味着條件只被評估一次,盡管它會不必要地分配我不會隨后使用的分組。
如何將結果放入LookUp
並在剩下的時間內使用它?
var lookup = data.ToLookUp(i => Foo(i));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.