将List <string>转换为List <keyvaluepair <string,string =“”>&gt;使用Linq </keyvaluepair <string,> </string>

时间:2012-08-16 06:41:40

标签: c# linq lambda

  

可能重复:
  Is there a LINQ way to go from a list of key/value pairs to a dictionary?

假设我有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 个答案:

答案 0 :(得分:8)

var output = Enumerable.Range(0, input.Count / 2)
                       .Select(i => Tuple.Create(input[i * 2], input[i * 2 + 1]))
                       .ToList();

答案 1 :(得分:5)

我不建议在这里使用LINQ,因为没有理由和你没有通过使用LINQ获得任何东西,而只是使用正常的for循环并在每次迭代中将计数变量增加2 :

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,我就不会遇到访问无效索引的异常1}}以“半对”值结束。

答案 2 :(得分:3)

你可以用这个:

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)));

答案 3 :(得分: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();

N.B。
即使您的初始输入变为通用IEnumerable<string>而非具体为List<string>

,此功能仍然有效