jyoung
jyoung

Reputation: 5181

Is there a statement to prepend an element T to a IEnumerable<T>

For example:

string element = 'a';
IEnumerable<string> list = new List<string>{ 'b', 'c', 'd' };

IEnumerable<string> singleList = ???; //singleList yields 'a', 'b', 'c', 'd' 

Upvotes: 26

Views: 11629

Answers (11)

videokojot
videokojot

Reputation: 551

Since .NET framework 4.7.1 there is LINQ method for that:

list.Prepend("a");

https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.prepend?view=netframework-4.7.1

Upvotes: 11

Rm558
Rm558

Reputation: 5002

As pointed out by Niklas & NetMage in the comments.

There is a new built-in Prepend methond in C#.

enter image description here

Upvotes: 0

zzzzBov
zzzzBov

Reputation: 179216

I find it convenient to be able to prepend multiple items in a chainable fashion. This version takes advantage of extension methods and params.

As a note, this version implicitly allows null, but it's just as easy to change it to throw new NullReferenceException() if that's the desired behavior.

public static class IEnumerableExtensions
{
    public static IEnumerable<T> Prepend<T>(this IEnumerable<T> source, params T[] items)
    {
        return items.Concat(source ?? new T[0]);
    }
}

Allows for a very readable syntax for individual items:

GetItems().Prepend(first, second, third);

...and for collections of items:

GetItems().Prepend(GetMoreItems());

Finishing the example in the question results in:

string element = "a";
IEnumerable<string> list = new List<string>{ "b", "c", "d" };

IEnumerable<string> singleList = list.Prepend(element);

Upvotes: 2

NetMage
NetMage

Reputation: 26926

Looking at some of the examples, I think I'd prefer to reverse the extension to apply to the object.

public static IEnumerable<T> PrependTo<T>(this T value, IEnumerable<T> values) {
    return new[] { value }.Concat(values);
}

Used like

var singleList = element.PrependTo(list);

Upvotes: 0

dr. rAI
dr. rAI

Reputation: 1833

Just as a reminder - List< T > is not the only type of container. If you find yourself adding elements to the front of the list quite frequently, you can also consider using Stack< T > to implement your container. Once you have a stack

var container = new Stack<string>(new string[] { "b", "c", "d" });

you can always "prepend" an element via

container.Push("a");

and still use the collection as IEnumerable< T > like in

foreach (var s in container)
    // do sth with s

besides all the other methods typical for a stack like Pop(), Peek(), ...

Some of the solutions above iterate through the whole IEnumeration< T > just to prepend one element (or more than one in one case). This can be a very expensive operation if your collection contains a large number of elements and the frequency of prepending is relatively high.

Upvotes: 1

Stack Overflow is garbage
Stack Overflow is garbage

Reputation: 248199

You can roll your own:

static IEnumerable<T> Prepend<T>(this IEnumerable<T> seq, T val) {
 yield return val;
 foreach (T t in seq) {
  yield return t;
 }
}

And then use it:

IEnumerable<string> singleList = list.Prepend(element);

Upvotes: 7

Marc Gravell
Marc Gravell

Reputation: 1063734

I take it you can't just Insert into the existing list?

Well, you could use new[] {element}.Concat(list).

Otherwise, you could write your own extension method:

    public static IEnumerable<T> Prepend<T>(
            this IEnumerable<T> values, T value) {
        yield return value;
        foreach (T item in values) {
            yield return item;
        }
    }
    ...

    var singleList = list.Prepend("a");

Upvotes: 35

BFree
BFree

Reputation: 103760

public static class IEnumerableExtensions
{
    public static IEnumerable<T> Prepend<T>(this IEnumerable<T> ie, T item)
    {
         return new T[] { item }.Concat(ie);
    }
}

Upvotes: 5

Josh G
Josh G

Reputation: 14256

Also:

IEnumerable<string> items = Enumerable.Repeat(item, 1).Concat(list);

Upvotes: 3

Martin Peck
Martin Peck

Reputation: 11564

This would do it...

IEnumerable<string> singleList = new[] {element}.Concat(list);

If you wanted the singleList to be a List then...

IEnumerable<string> singleList = new List<string>() {element}.Concat(list);

... works too.

Upvotes: 5

Anton Gogolev
Anton Gogolev

Reputation: 115859

No, there's no such built-in statment, statement, but it's trivial to implement such function:

IEnumerable<T> PrependTo<T>(IEnumerable<T> underlyingEnumerable, params T[] values)
{
    foreach(T value in values)
        yield return value;

    foreach(T value in underlyingEnumerable)
        yield return value;
}

IEnumerable<string> singleList = PrependTo(list, element);

You can even make it an extension method if C# version allows for.

Upvotes: 1

Related Questions