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


74

给定两个 相同大小的IEnumerables ,如何 使用Linq将其转换为a Dictionary

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,并使用索引检索另一个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

Answers:


139

使用.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);

竖起大拇指。很高兴将其纳入BCL。我已经有很长时间了。
支出者

1
@spender-即使您自己制作,我也会从Eric Lipperts博客中获取
奥利弗2010年

2
可惜的是需要一种Zip方法。如果仅更多静态类型的语言支持通用可变参数,Select则将对此进行处理(如mapScheme中)。
嬉皮

太棒了!谢谢
Yevgraf Andreyevich Zhivago 2014年

32

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

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

(如果values保留为List<string>,则为...)


1
真漂亮 我正是在寻找那个。Linq很方便,但是您需要使用它编写的代码确实使IMO感到困惑。
Nyerguds 2010年

14

我喜欢这种方法:

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

1

如果使用MoreLINQ,还可以在以前创建的s上使用它的ToDictionary扩展方法KeyValuePair

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

还应注意,使用Zip扩展方法可以安全地防止不同长度的输入集合。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.