1. ホーム
  2. c#

[解決済み] C#で2つのリストを辞書にマップする

2023-05-24 10:20:51

質問

与えられた2つの IEnumerable s に変換するにはどうしたらよいでしょうか。 Dictionary Linqを使って?

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

var dictionary = /* Linq ? */;

そして、期待される出力は

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

何か簡単に実現する方法はないでしょうか。

また、パフォーマンスを心配する必要があるのでしょうか?大きなコレクションがある場合はどうすればいいのでしょうか?


もっと簡単な方法はないでしょうか、現在はこのようにやっています。

をループさせるExtensionメソッドを持っています。 IEnumerable をループし、要素とインデックス番号を提供します。

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

そして、Enumerableの1つをループし、そのインデックスで他のEnumerable上の同等の要素を取得するメソッドを持っています。

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

という感じで使っています。

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

そして、出力は正しいです。

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

どのように解決するのですか?

.NET 4.0 (または Rx の System.Interactive の 3.5 バージョン) では Zip() :

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