这应该很简单,但我想不出一个好的方法。如何将ILookup转换为另一个ILookup?例如,如何复制/克隆一个ILookup,生成另一个具有相同密钥和相同组的ILookup?
这是我的失败尝试:
static ILookup<TKey, TValue> Copy<TKey, TValue>(ILookup<TKey, TValue> lookup)
{
return lookup
.ToDictionary(
grouping => grouping.Key,
grouping => grouping.ToArray())
.SelectMany(pair =>
pair
.Value
.Select(value =>
new KeyValuePair<TKey, TValue>(pair.Key, value)))
.ToLookup(pair => pair.Key, pair => pair.Value);
}有人能改进这一点吗?
--布莱恩
发布于 2010-11-07 11:43:32
这是你想要的吗?
static ILookup<TKey, TValue> Copy<TKey, TValue>(ILookup<TKey, TValue> lookup)
{
return lookup.
SelectMany(g => g,
(g, v) => new KeyValuePair<TKey, TValue>(g.Key, v)).
ToLookup(kvp => kvp.Key, kvp => kvp.Value);
}当然,如果您想以某种方式转换这些值,可能需要如下所示:
static ILookup<TKey, TValueOut> Transform<TKey, TValue, TValueOut>(
ILookup<TKey, TValue> lookup,
Func<TValue, TValueOut> selector)
{
return lookup.
SelectMany(g => g,
(g, v) => new KeyValuePair<TKey, TValueOut>(g.Key, selector(v))).
ToLookup(kvp => kvp.Key, kvp => kvp.Value);
}请注意,此方法保存KeyValuePair中的中间值,它是一种值类型,存储在堆栈中,因此不需要任何中间内存分配。我分析了一个测试,该测试创建一个具有100个键的Lookup<int,int>,每个键有10,000个项(总共有1,000,000个项)。
使用我的方法创建
Lookup所需的所有分配加上SelectMany调用中的每个委托一个分配,以及使用匿名对象而不是KeyValuePair创建Lookup的每个枚举器分配一个分配)进行1,001,712次分配(复制所需的所有分配加上每个项目一次分配)。就CPU而言,即使Lookup中每个键有100,000个元素,两种复制方法之间的性能也是相同的。在每个键有1,000,000个元素的情况下,两种方法的性能有所不同:
使用匿名对象创建匿名对象5.1秒创建匿名对象5.9秒使用KeyValuePair
发布于 2010-11-07 11:33:59
这样如何:
return lookup
.SelectMany (grp => grp, (grp, item) => new { grp.Key, item})
.ToLookup (x => x.Key, x => x.item);https://stackoverflow.com/questions/4115676
复制相似问题