0

to do it in linqI have an integer List and want to group these to a list of integer pairs.

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

result should be: {{1, 24}, {3, 2}, {26, 11}, {18, 13}}

I tried:

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

Is there a better way to do it in linq?

Of course I can do it with a simple for-loop.

Edit: I think I give MoreLinq a try. I also mark this as the answer even if it's an extension and not pure linq.

By the way - I think doing it with a for-loop is much more understandable.

GreenEyedAndy
  • 1,485
  • 1
  • 14
  • 31

5 Answers5

4

You can use MoreLINQ Batch to split your input into a list of "length 2" lists. Or any other length you want.

List<int> src = new List<int> { 1, 24, 3, 2, 26, 11, 18, 13 };
List<IEnumerable<int>> wanted = src.Batch(2).ToList();
Hans Kesting
  • 38,117
  • 9
  • 79
  • 111
1

No need for MoreLINQ; Enumerate even- and odd-indexed values, and 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();
Fredrik
  • 2,247
  • 18
  • 21
0

If you can garantee, that the length of the source can always be devided by 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]); 
scher
  • 1,813
  • 2
  • 18
  • 39
0

a simple for loop is enough for this.Just start with 1 and increment it by 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]));
}

In case of odd count last item will be skipped

ClearLogic
  • 3,616
  • 1
  • 23
  • 31
0

Another simple loop solution featuring C# 7 tuples.

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]));
}
bklaric
  • 447
  • 6
  • 15