Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Repeat list endlessly (Zip a finite list with an Infinite repeating sequence)

Tags:

c#

linq

UserList is a list of dictionaries, like:

[
  {Name:"Alex",Age:25},
  {Name:"Peter",Age:35},
  {Name:"Muhammad",Age:28},
  {Name:"Raul",Age:29}
]

RowColorList is a list of colors: [#bcf,#fc0]

The new UserList should contain one RowColor for every name, taken in sequence from RowColorList:

[
  {Name:"Alex",Age:25,RowColor:#bcf},
  {Name:"Peter",Age:35,RowColor:#fc0},
  {Name:"Muhammad",Age:28,RowColor:#bcf},
  {Name:"Raul",Age:29,RowColor:#fc0}
]

I tried the following code:

UserList.Zip(RowColorList,(user,color) => user.Add("RowColor",color))

With this code, the new UserList will only contain as many entries as are in RowColorList. I would like him to start from the beginning of RowColorList again, whenever the available colors are used up. How?

like image 714
Alexander Avatar asked Dec 24 '22 23:12

Alexander


1 Answers

You can create a function to return an infinite enumerable of Color / string (or whatever the type of RowColor is), by using yield return as a lazy generator:

public IEnumerable<Color> InfiniteColors()
{
    while (true)
    {   
        foreach (var color in RowColors)
        {
            yield return color;
        }
    }
}

This can then be used with any of the Linq IEnumerable extension methods such as Zip.

UserList.Zip(InfiniteColors(),(user,color) => user.Add("RowColor",color))

Edit - Explanation

The reason why InfiniteColors doesn't hang is because the state machine will yield back to the caller after each result, and Zip will terminate on the first enumerable to complete, which is because the other collection being zipped is finite (i.e. UserList)

Obviously you shouldn't try and Zip the InfiniteColors enumerable with itself, nor should you try and materialize InfiniteColors, i.e. don't call InfiniteColors.ToList() or such :-):

like image 160
StuartLC Avatar answered Dec 27 '22 17:12

StuartLC