Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# interweave two uneven List into a new List

Tags:

c#

linq

I have two List, both of different lengths. What I am trying to achieve is a third List that contains the first element from list1, then the first element from list2, then second element from list1, and second element from list2, and so on until one of the two has been exhausted (they're uneven), and then just add in any remaining items from that list.

result should have the same number of items as list1 and list2 combined.

I cannot use something like Union.ToList() as that doesn't interweave the two, it just adds all of the items from for example list1 to the bottom of list2 and outputs it as result. I tried .Zip(Linq) however that seems to take in the two elements and merged them into a single element (namely concatenating the two strings into one longer string).

List<string> list1 = new List<string>(){
            "4041",
            "4040"              
        };

List<string> list2 = new List<string>(){ 
            "4039",
            "4044", 
            "4075", 
            "4010",
            "4100",
            "4070", 
            "4072" 
        };


// Ideal result:    
result = { "4041",
      "4039",
      "4040"  
      "4044",      
      "4075", 
      "4010",
      "4100",
      "4070", 
      "4072" 
}; 
like image 796
Safari Jones Avatar asked Feb 13 '23 12:02

Safari Jones


2 Answers

int length = Math.Min(list1.Count, list2.Count);

// Combine the first 'length' elements from both lists into pairs
list1.Take(length)
.Zip(list2.Take(length), (a, b) => new int[] { a, b })
// Flatten out the pairs
.SelectMany(array => array)
// Concatenate the remaining elements in the lists)
.Concat(list1.Skip(length))
.Concat(list2.Skip(length));
like image 134
Barak Itkin Avatar answered Feb 15 '23 10:02

Barak Itkin


If you don't need to keep the original lists intact, you can use a while loop to pop items off the front of each list:

while(list1.Count > 0 || list2.Count > 0)
{
    if(list1.Count > 0)
    {
        combinedList.Add(list1[0]);
        list1.RemoveAt(0);
    } 

    if(list2.Count > 0)
    {
        combinedList.Add(list2[0]);
        list2.RemoveAt(0);
    } 
}

Not quite as terse as Linq but easy to read and very clear what is going on.

like image 37
bingles Avatar answered Feb 15 '23 10:02

bingles