3

I have a given data (I just make it as a List here).

List<string> list1 = new List<string>();
foreach( var x in Regex.Split( "A B C D E F", " " ) )
    list1.Add( x );

Now I want to make a final List like this.

List<string[]> list2 = new List<string[]>();

So, I tried with this code (I have tried with LINQ but, no gain).

int i = 0;
string[] array1 = new string[2];
foreach( var x in list1 )
{
    if( i % 2 == 0 )
    {
        array1[0] = x;
    }
    else
    {
        array1[1] = x;
        list2.Add( array1 );
        array1 = new string[2];
    }
    i++;
}

I'd like to use LINQ for the same result. Please help.

Thanks.

(EDIT: Result should be A and B, C and D, E and F for each item in List 2)

2
  • Side note: the first list can also be obtained with the string's native split method and ToList with: List<string> list1 = "A B C D E F".Split(' ').ToList(); Commented Dec 18, 2016 at 9:25
  • @Me.Name Yes, You are right. But, that one is "given". Thanks. Commented Dec 18, 2016 at 9:27

4 Answers 4

5

Try this:

List<string[]> list2 = list1
               .Select((value, index) => new { PairNum = index / 2, value })
               .GroupBy(pair => pair.PairNum)
               .Select(grp => grp.Select(g => g.value).ToArray())
               .ToList();

The steps are:

  1. Select((value, index) => new { PairNum = index / 2, value }) => {0, 'A'} {0, 'B'} {1, 'C'} {1, 'D'} {2, 'E'} {2, 'F'}

  2. GroupBy(pair => pair.PairNum) => {0:{'A', 'B'}}, {1:{'C', 'D'}}, {2:{'E', 'F'}}

  3. Select(grp => grp.Select(g => g.value).ToArray()) => converts values to array because list items should be arrays.
  4. Executes the query
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks. Looks like super difficult. I'll try it.
I added a comment to explain a little bit.
Ahhh. I'm begining to understand it. (Not finished yet though) Thanks for the nice explanations too.
1
list2 = list1.Where((x, i) => i % 2 == 0)
     .Zip(list1.Where((x, i) => i % 2 == 1),
           (x, y) => new[] { x, y })
           .ToList();

1 Comment

Thanks. It is interesting too.
1

This is super easy with following trick..

var result = Enumerable.Range(0,array.Count()/2)
                       .Select(x=>array.Skip(x*2).Take(2));

Comments

1

What you want to do is the opposite of SelectMany, for which there is no built-in way. There is also no way to also iterate in steps of two. But since your source is an array, you can access its contents by index:

string[] sourceItems = sourceStr.Split(" ");

var pairQry =
    from index in Enumerable.Range(0, sourceItems.Length - 1)
    where index % 2 == 0
    select new string[] { sourceItems[index], sourceItems[index + 1] };

List<string[]> pairs = pairQry.ToList();

1 Comment

Wow, I din not think that my question is not so easy one. OK. This is a good point to learn LINQ. Thanks.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.