wake-up-neo.net

Zuordnung von zwei Listen zu einem Wörterbuch in C #

Wenn ich zwei IEnumerables der gleichen Größe habe, wie kann ich es mit Linq in eine Dictionary konvertieren?

IEnumerable<string> keys = new List<string>() { "A", "B", "C" };
IEnumerable<string> values = new List<string>() { "Val A", "Val B", "Val C" };

var dictionary = /* Linq ? */;

Und der erwartete Output ist:

A: Val A
B: Val B
C: Val C

Ich frage mich, ob es einen einfachen Weg gibt, dies zu erreichen.

Und sollte ich mir Sorgen um die Leistung machen? Was ist, wenn ich große Sammlungen habe?


Ich weiß nicht, ob es einen einfacheren Weg gibt, derzeit mache ich Folgendes:

Ich habe eine Erweiterungsmethode, die die IEnumerable-Schleife durchläuft und mir das Element und die Indexnummer zur Verfügung stellt.

public static class Ext
{
    public static void Each<T>(this IEnumerable els, Action<T, int> a)
    {
        int i = 0;
        foreach (T e in els)
        {
            a(e, i++);
        }
    }
}

Und ich habe eine Methode, die eine der Enumerables in einer Schleife durchläuft und mit dem Index das entsprechende Element auf der anderen Enumerable abruft.

public static Dictionary<TKey, TValue> Merge<TKey, TValue>(IEnumerable<TKey> keys, IEnumerable<TValue> values)
{
    var dic = new Dictionary<TKey, TValue>();

    keys.Each<TKey>((x, i) =>
    {
        dic.Add(x, values.ElementAt(i));
    });

    return dic;
}

Dann benutze ich es wie:

IEnumerable<string> keys = new List<string>() { "A", "B", "C" };
IEnumerable<string> values = new List<string>() { "Val A", "Val B", "Val C" };

var dic = Util.Merge(keys, values);

Und die Ausgabe ist korrekt:

A: Val A
B: Val B
C: Val C
56
BrunoLM

Mit .NET 4.0 (oder der Version 3.5 von System.Interactive von Rx) können Sie Zip() verwenden:

var dic = keys.Zip(values, (k, v) => new { k, v })
              .ToDictionary(x => x.k, x => x.v);
114
dahlbyk

Basierend auf Ihrer Idee enthält LINQ eine Überladung von Select(), die den Index bereitstellt. Kombiniert mit der Tatsache, dass values den Zugriff über den Index unterstützt, könnte man Folgendes tun:

var dic = keys.Select((k, i) => new { k, v = values[i] })
              .ToDictionary(x => x.k, x => x.v);

(Wenn values als List<string> beibehalten wird, heißt das ...)

22
dahlbyk

Ich mag diesen Ansatz:

var dict =
   Enumerable.Range(0, keys.Length).ToDictionary(i => keys[i], i => values[i]);
10
Todd Menier

Wenn Sie MoreLINQ verwenden, können Sie auch die Erweiterungsmethode ToDictionary für zuvor erstellte KeyValuePairs verwenden:

var dict = Enumerable
    .Zip(keys, values, (key, value) => KeyValuePair.Create(key, value))
    .ToDictionary();

Es sollte auch beachtet werden, dass die Verwendung der Erweiterungsmethode Zip für Eingabesammlungen unterschiedlicher Länge sicher ist.

0
Deilan