8

可能重复:
是否有 LINQ 方法可以从键/值对列表到字典?

假设我有一个List<string>如下:

var input = new List<string>()
                       {
                           "key1",
                           "value1",
                           "key2",
                           "value2",
                           "key3",
                           "value3",
                           "key4",
                           "value4"
                       };

基于此列表,我想转换为List<KeyValuePair<string, string>>,原因是允许相同的键,这就是我不使用 Dictionary 的原因。

var output = new List<KeyValuePair<string, string>>()
                       {
                           new KeyValuePair<string, string>("key1", "value1"),
                           new KeyValuePair<string, string>("key2", "value2"),
                           new KeyValuePair<string, string>("key3", "value3"),
                           new KeyValuePair<string, string>("key4", "value4"),
                       };

我可以通过使用以下代码来实现:

var keys = new List<string>();
var values = new List<string>();

for (int index = 0; index < input.Count; index++)
{
    if (index % 2 == 0) keys.Add(input[index]);
    else values.Add(input[index]);
}

var result = keys.Zip(values, (key, value) => 
                        new KeyValuePair<string, string>(key, value));

但是感觉这不是使用循环的最佳方式for,有没有其他方法可以使用内置的 LINQ 来实现呢?

4

4 回答 4

10
var output = Enumerable.Range(0, input.Count / 2)
                       .Select(i => Tuple.Create(input[i * 2], input[i * 2 + 1]))
                       .ToList();
于 2012-08-16T06:52:02.080 回答
6

我不建议在这里使用 LINQ,因为实际上没有理由使用 LINQ,而且您不会通过使用 LINQ 获得任何东西,而只是使用普通for循环并在每次迭代中将计数变量增加两个:

var result = new List<KeyValuePair<string, string>>();

for (int index = 1; index < input.Count; index += 2)
{
    result.Add(new KeyValuePair<string, string>(input[index - 1], input[index]));
}

请注意,我开始我的索引,1所以我不会遇到访问无效索引的异常,以防万一中的项目数input是奇数,即如果input以“半对”值结尾。

于 2012-08-16T06:45:33.740 回答
4

你可以使用这个:

IEnumerable<KeyValuePair<string, string>> list = 
        input.Where((s, i) => i % 2 == 0)
             .Select((s, i) => new KeyValuePair<string, string>(s, input.ElementAt(i * 2 + 1)));
于 2012-08-16T07:09:04.457 回答
0

您可以使用 LINQ Aggregate() 函数(代码比简单循环长):

var result = 
input.Aggregate(new List<List<string>>(),
                (acc, s) =>
                {
                    if (acc.Count == 0 || acc[acc.Count - 1].Count == 2)
                        acc.Add(new List<string>(2) { s });
                    else
                        acc[acc.Count - 1].Add(s);
                    return acc;
                })
                .Select(x => new KeyValuePair<string, string>(x[0], x[1]))
                .ToList();

请注意
,即使您的初始输入变成通用的IEnumerable<string>而不是专门的List<string>

于 2012-08-16T06:52:20.257 回答