2

これは単純なはずですが、私はそれを行うための良い方法を考えることができません。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);
}

誰かがこれを改善できますか?

-ブライアン

4

2 に答える 2

4

これはどう:

return lookup
  .SelectMany (grp => grp, (grp, item) => new { grp.Key, item})
  .ToLookup (x => x.Key, x => x.item);
于 2010-11-07T03:33:58.813 に答える
2

これはあなたが望むことをしますか?

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個)があります。

  • Lookup1610の割り当てを作成します。
  • 私のメソッドでそれをコピーすると、1712の割り当てが行われます(作成に必要なすべての割り当てに加えて、SelectMany呼び出しの各デリゲートに1つ、各キーの列挙子に1つ)。
  • 1,001,712の割り当てではなく、匿名オブジェクトを使用しKeyValuePairてコピーします(コピーに必要なすべての割り当てに加えて、アイテムごとに1つ)。

CPUに関しては、キーごとに100,000の要素がある場合でもLookup、2つのコピー方法間のパフォーマンスは同じでした。キーごとに1,000,000の要素があるため、パフォーマンスは2つの方法で異なります。

  • 作成する5.1秒
  • コピーに5.9秒KeyValuePair
  • 匿名オブジェクトでコピーするのに6.3秒
于 2010-11-07T03:43:32.280 に答える