将两个列表映射到C#中的字典

Bru*_*oLM 67 .net c# linq ienumerable dictionary

给定两个 相同大小的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 ? */;
Run Code Online (Sandbox Code Playgroud)

而预期的产出是:

A: Val A
B: Val B
C: Val C
Run Code Online (Sandbox Code Playgroud)

我想知道是否有一些简单的方法来实现它.

我应该担心表现吗?如果我有大量收藏怎么办?


如果有更简单的方法,我不会这样做,目前我这样做:

我有一个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++);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我有一个方法将循环其中一个Enumerables并使用索引检索另一个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;
}
Run Code Online (Sandbox Code Playgroud)

然后我用它像:

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);
Run Code Online (Sandbox Code Playgroud)

输出正确:

A: Val A
B: Val B
C: Val C
Run Code Online (Sandbox Code Playgroud)

dah*_*byk 127

使用.NET 4.0(或Rx的3.5版System.Interactive),您可以使用Zip():

var dic = keys.Zip(values, (k, v) => new { k, v })
              .ToDictionary(x => x.k, x => x.v);
Run Code Online (Sandbox Code Playgroud)

  • 到 2022 年,它可以更短为 `var dic =keys.Zip(values).ToDictionary(x =&gt; x.First, x =&gt; x.Second);` (5认同)
  • 可惜的是,需要一种“ Zip”方法。如果只有更多的静态类型语言支持通用的可变参数,则“选择”将处理该问题(例如Scheme中的“ map”)。 (2认同)

dah*_*byk 27

或者根据您的想法,LINQ包含一个Select()提供索引的重载.结合values支持索引访问的事实,可以执行以下操作:

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

(如果values保持为List<string>,那就是...)


Tod*_*ier 11

我喜欢这种方法:

var dict =
   Enumerable.Range(0, keys.Length).ToDictionary(i => keys[i], i => values[i]);
Run Code Online (Sandbox Code Playgroud)