Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ: Adding an item to every second position

Tags:

c#

linq

so I have a list:

["item1"]
["item2"]
["item3"]

and I want the list to be like this:

[""]
["item1"]
[""]
["item2"]
[""]
["item3"]

A simple back-to-front loop gives me just that:

for (int i = list.Count-1; i >= 0; i--)
   list.Insert(i, string.Empty);

But I'm wondering if there is a more elegant way to do this with LINQ?

like image 332
Pompair Avatar asked Nov 05 '14 09:11

Pompair


3 Answers

You could use an Intersperse extension method. That way, the meaning is clear and the code is reusable. Code taken from Extension method for Enumerable.Intersperse with slight modification to also include an empty string in the first position.

public static IEnumerable<T> Intersperse<T>(this IEnumerable<T> source, T element)
{
    foreach (T value in source)
    {
        yield return element;
        yield return value;
    }
}
like image 100
mihai Avatar answered Oct 15 '22 20:10

mihai


Here is a way to do it:

list = list.SelectMany(x => new [] { string.Empty, x }).ToList();

But it's worth noting that this creates unnecessary arrays.If your list is big enough that might be a problem. Instead I would create a new list with a capacity and populate it using loop:

var newList = new List<string>(list.Count * 2);
int j = 0;
for(int i = 0; i < list.Count * 2; i++)
    newList.Add(i % 2 == 0 ? string.Empty : list[j++]);

This will avoid resizing the list each time you add or insert items.

like image 9
Selman Genç Avatar answered Oct 15 '22 22:10

Selman Genç


You can do it using SelectMany LINQ extension:

void Main()
{
    List<String> items = new List<String>()
    {
        "1",
        "2",
        "3"
    };

    var result = items
        .SelectMany(item => new String[] {"Some value", item})
        .ToList();

    PrintItems(result);
}

void PrintItems<T>(IEnumerable<T> items)
{
    foreach(var item in items)
    {
        Console.WriteLine(item);
    }
}

But as you understand it is not the most effective way.

like image 2
Eugene Podskal Avatar answered Oct 15 '22 22:10

Eugene Podskal