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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.