使用Linq 将List 转换为List <KeyValuePair >

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

假设我有一个List ,如下所示:

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

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

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

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

 var keys = new List(); var values = new List(); for (int index = 0; index  new KeyValuePair(key, value)); 

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

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

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

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

请注意,我正在以1开始索引,因此如果input的项目数为奇数,即input以“半对”值结束,则不会遇到访问无效索引的exception。

你可以用这个:

 IEnumerable> list = input.Where((s, i) => i % 2 == 0) .Select((s, i) => new KeyValuePair(s, input.ElementAt(i * 2 + 1))); 

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

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

NB
即使您的初始输入变为通用的IEnumerable而不是特定的List