This should be simple, but I can't think of a good way to do it. How do you transform an ILookup into another ILookup? For example, how would you copy/clone an ILookup, producing another ILookup with the same keys and same groups?
Here's my lame attempt:
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);
}
Can anyone improve this?
-- Brian
Does this do what you want?
Of course, if you want to transform the values somehow, maybe you want something like this:
Note that this method holds intermediate values in a
KeyValuePair
which, being a value type, is stored on the stack and thus doesn't require any intermediate memory allocations. I profiled a test that creates aLookup<int,int>
with 100 keys, each having 10,000 items (for a total of 1,000,000).Lookup
does 1610 allocations.SelectMany
call and one for the enumerator for each key).KeyValuePair
does 1,001,712 allocations (all the allocations required to copy plus one for each item).CPU-wise, even with 100,000 elements per key in the
Lookup
performance between the two copying methods was identical. With 1,000,000 elements per key, the performance was different between the two methods:KeyValuePair