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

Posted

技术标签:

【中文标题】将两个列表映射到 C# 中的字典中【英文标题】:Map two lists into a dictionary in C# 【发布时间】:2011-05-01 15:19:56 【问题描述】:

给定两个 IEnumerables 大小相同,我如何将其转换为 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

不知道有没有什么简单的方法可以实现。

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


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

我有一个扩展方法,它将循环 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

【问题讨论】:

【参考方案1】:

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

【讨论】:

为 .Zip 点赞。很高兴它进入了 BCL。我有自己的版本已经有一段时间了。 @spender - 即使你自己制作,我也会从Eric Lipperts Blog获取它 可惜需要Zip 方法。如果只有更多的静态类型语言支持泛型可变参数,Select 就会处理这个问题(就像 Scheme 中的 map)。 太棒了!谢谢【参考方案2】:

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

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

(如果values保持为List&lt;string&gt;,那就是……)

【讨论】:

哦,漂亮!我正是在寻找那个。 Linq 很方便,但是你需要用它编写的代码看起来真的很混乱 IMO。【参考方案3】:

我喜欢这种方法:

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

【讨论】:

【参考方案4】:

如果您使用MoreLINQ,您还可以在之前创建的KeyValuePairs 上使用它的ToDictionary 扩展方法:

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

还需要注意的是,使用Zip扩展方法对于不同长度的输入集合是安全的。

【讨论】:

以上是关于将两个列表映射到 C# 中的字典中的主要内容,如果未能解决你的问题,请参考以下文章

将字典列表中的值映射到 Python 中的字符串

将列表字典映射到熊猫 df

将字典映射到数据框列中的列表

将两个列表合并成字典的方法

C#如何匹配两个列表框中的项目

C#中如何将两个项目合并到一个项目中