Frage

Dies sollte einfach sein, aber ich kann eine gute Art und Weise nicht denken, es zu tun. Wie kann ein ILookup in einer anderen ILookup verwandeln? Zum Beispiel, wie würden Sie kopieren / Klon ein ILookup, eine andere ILookup mit den gleichen Schlüsseln und gleichen Gruppen produzieren?

Hier ist mein lahmer Versuch:

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);
}

Kann jemand dies verbessern?

- Brian

War es hilfreich?

Lösung

Ist das tun, was Sie wollen?

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);
}

Natürlich, wenn Sie die Werte irgendwie umwandeln wollen, vielleicht wollen Sie etwas wie folgt aus:

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);
}

Hinweis, dass dieses Verfahren in einem Zwischenwert KeyValuePair hält, die einen Wert ein, wobei auf dem Stapel abgelegt wird und somit keine Zwischenspeicherzuordnungen erfordern. Ich Profil einen Test, der eine Lookup<int,int> mit 100 Tasten erzeugt, die jeweils 10.000 Stück (für insgesamt 1.000.000).

  • Erstellen der Lookup hat 1610 Zuweisungen.
  • Kopiert es mit meiner Methode macht 1712 Zuweisungen (alle Zuweisungen erforderlich, um es zu schaffen und einen für jeden Teilnehmer in dem SelectMany Anruf und ein für den Enumerator für jede Taste).
  • es mit anonymen Kopieren von Objekten statt KeyValuePair tut 1.001.712 Zuweisungen (alle die Zuweisungen erforderlich plus eins für jedes Element zu kopieren).

CPU-weise, sogar mit 100.000 Elemente pro Schlüssel in der Lookup Leistung zwischen den beiden Kopierverfahren waren identisch. Mit 1.000.000 Elementen pro Schlüssel war die Leistung unterschiedlich zwischen den beiden Methoden:

  • 5.1 sec erstellen
  • 5.9 sec mit KeyValuePair kopieren
  • 6.3 sec mit anonym kopieren Objekte

Andere Tipps

Wie wäre es damit:

return lookup
  .SelectMany (grp => grp, (grp, item) => new { grp.Key, item})
  .ToLookup (x => x.Key, x => x.item);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top