鉴于两个相同大小的 IEnumerable
s ,如何使用Linq将其转换为 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++);
}
}
}
我有一个方法可以循环其中一个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;
}
然后我就像使用它一样:
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
答案 0 :(得分:116)
使用.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);
答案 1 :(得分:23)
或者根据您的想法,LINQ包含提供索引的Select()
重载。结合values
支持索引访问的事实,可以执行以下操作:
var dic = keys.Select((k, i) => new { k, v = values[i] })
.ToDictionary(x => x.k, x => x.v);
(如果values
保持为List<string>
,那就是......)
答案 2 :(得分:11)
我喜欢这种方法:
var dict =
Enumerable.Range(0, keys.Length).ToDictionary(i => keys[i], i => values[i]);
答案 3 :(得分:0)
如果您使用MoreLINQ,则还可以在之前创建的KeyValuePair
上使用ToDictionary扩展方法:
var dict = Enumerable
.Zip(keys, values, (key, value) => KeyValuePair.Create(key, value))
.ToDictionary();
还应该注意,使用Zip
扩展方法对于不同长度的输入集合是安全的。