这应该很简单,但我想不出一个好方法。你如何将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);
}
任何人都可以改进吗?
- Brian
答案 0 :(得分:4)
这个怎么样:
return lookup
.SelectMany (grp => grp, (grp, item) => new { grp.Key, item})
.ToLookup (x => x.Key, x => x.item);
答案 1 :(得分:1)
这样做你想要的吗?
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
会执行1610次分配。SelectMany
调用中每个代理的一个分配,以及每个密钥的枚举器一个分配。)KeyValuePair
复制它会进行1,001,712次分配(复制所需的所有分配加上每个项目的分配)。在CPU方面,即使两个复制方法之间的Lookup
性能中每个键有100,000个元素也是相同的。每个键有1,000,000个元素,两种方法的性能不同:
KeyValuePair