Map two lists into a dictionary in C#
Given two IEnumerable
s of the same size, how can I convert it to a Dictionary
using 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 ? */;
And the expected output is:
A: Val A
B: Val B
C: Val C
I wonder if there is some simple way to achieve it.
And should I be worried about performance? What if I have large collections?
I don't if there is an easier way to do it, currently I'm doing like this:
I have an Extension method that will loop the IEnumerable
providing me the element and the index number.
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++);
}
}
}
And I have a method that will loop one of the Enumerables and with the index retrieve the equivalent element on the other 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;
}
Then I use it like:
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);
And the output is correct:
A: Val A
B:开发者_如何学C Val B
C: Val C
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 KeyValuePair
s:
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.
精彩评论