从列表中构建对 - 不重复

时间:2017-08-04 07:41:25

标签: c# linq

在linqI中执行它有一个整数列表,并希望将这些组合成一个整数对列表。

var input = new[] {1, 24, 3, 2, 26, 11, 18, 13};

结果应为:{{1, 24}, {3, 2}, {26, 11}, {18, 13}}

我试过了:

List<int> src = new List<int> { 1, 24, 3, 2, 26, 11, 18, 13 };
var agr = src.Select((n, i) => new Tuple<int, int>(i++ % 2, n))
             .GroupBy(t => t.Item1)
             .ToList();

var wanted = agr[0].Zip(agr[1], (d, s) => new Tuple<int, int>(d.Item2, s.Item2));

在linq中有更好的方法吗?

当然,我可以通过一个简单的for循环来实现。

修改 我想我试试一下MoreLinq。我也将此标记为答案,即使它是一个扩展而不是纯粹的linq。

顺便说一下 - 我认为用for循环做这件事更容易理解。

5 个答案:

答案 0 :(得分:4)

您可以使用MoreLINQ Batch将输入拆分为“长度2”列表。或者你想要的任何其他长度。

List<int> src = new List<int> { 1, 24, 3, 2, 26, 11, 18, 13 };
List<IEnumerable<int>> wanted = src.Batch(2).ToList();

答案 1 :(得分:1)

不需要MoreLINQ;枚举偶数和奇数索引值,以及Zip

int[] input = new int[8] { 1, 24, 3, 2, 26, 11, 18, 13 };

var evenPositioned = input.Where((o, i) => i % 2 == 0);
var oddPositioned = input.Where((o, i) => i % 2 != 0);
var wanted = evenPositioned.Zip(oddPositioned, (even, odd) => new { even, odd }).ToList();

答案 2 :(得分:0)

如果你可以保证,源的长度总是可以用2分开:

List<int> src = new List<int> { 1, 24, 3, 2, 26, 11, 18, 13 };
var Tuple<int, int>[] wanted = new Tuple<int, int>[src.Count /2];
for(var i = 0; i < src.Count; i = i + 2)
    wanted[i/2] = new Tuple<int, int>(src[i], src[i+1]); 

答案 3 :(得分:0)

一个简单的for循环就足够了。只需从1开始,然后将其递增2

List<int> src = new List<int> { 1, 24, 3, 2, 26, 11, 18, 13 };
var list = new List<Tuple<int, int>>();
for(int i =1;i<src.Count;i=i+2)
{
    list.Add(new Tuple<int, int>(src[i-1],src[i]));
}

如果是奇数,则会跳过最后一项

答案 4 :(得分:0)

另一个以C#7元组为特色的简单循环解决方案。

var input = new List<int> { 1, 24, 3, 2, 26, 11, 18, 13 };
var wanted = new List<(int, int)>();
for (var index = 0; index < input.Count; index += 2) {
    wanted.Add((input[index], input[index + 1]));
}