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

使用 Linq 给出两个 IEnumerables 我怎样才能把它转换成一个 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

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

我是否应该担心性能问题? 如果我有大量的收集,该怎么办?


我不知道是否有更简单的方法,目前我是这样做的:

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

我有一个方法,它将循环其中一个 Enumerables,并使用索引检索另一个 Enumerables 上的等效元素。

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
54989 次浏览

With .NET 4.0 (or the 3.5 version of System.Interactive from Rx), you can use Zip():

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

Or based on your idea, LINQ includes an overload of Select() that provides the index. Combined with the fact that values supports access by index, one could do the following:

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

(If values is kept as List<string>, that is...)

I like this approach:

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

If you use MoreLINQ, you can also utilize it's ToDictionary extension method on previously created KeyValuePairs:

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

It also should be noted that using Zip extension method is safe against input collections of different lengths.