假设您有一个大型数据集,该数据集可能会也可能不会根据数据集元素的特定条件进行筛选,这些数据集元素可能需要密集的计算。在未过滤的情况下,按该条件的值对元素进行分组-该条件只计算一次。
然而,在过滤已经发生的情况下,尽管后续代码仍然期望看到IEnumerable<IGrouping<TKey, TElement>>集合,但是执行GroupBy操作是没有意义的,因为它会导致对每个元素的条件进行第二次重新评估。相反,我希望能够通过适当地包装过滤结果来创建IEnumerable<IGrouping<TKey, TElement>>,从而避免对条件进行另一次评估。
除了实现我自己的提供IGrouping接口的类之外,还有没有其他方法可以实现这种优化?有没有现有的LINQ方法支持这一点,从而给出IEnumerable<IGrouping<TKey, TElement>>结果?有没有其他我没有考虑过的方法?
发布于 2009-07-08 21:08:47
受David B's answer的启发,我想出了一个简单的解决方案。如此简单,以至于我都不知道我是如何错过它的。
为了执行过滤,我显然需要知道我正在过滤的条件的值。因此,在给定条件c的情况下,我可以将过滤后的列表投影为:
filteredList.GroupBy(x => c)这避免了对元素(由x表示)上的任何属性进行重新计算。
我意识到的另一个可行的解决方案是颠倒查询的顺序,并在执行过滤之前执行分组。这也意味着条件只会被评估一次,尽管它会不必要地分配我随后不会使用的分组。
发布于 2009-07-08 21:00:42
条件计算一次
我希望那些钥匙还在某个地方。
如果你的数据是这样的结构:
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)发布于 2009-07-08 20:56:28
把结果放到LookUp中,然后在剩下的时间里使用它,怎么样?
var lookup = data.ToLookUp(i => Foo(i));https://stackoverflow.com/questions/1100461
复制相似问题