Reputation: 5181
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
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
Reputation: 5002
As pointed out by Niklas & NetMage in the comments.
There is a new built-in Prepend methond in C#.
Upvotes: 0
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
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
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
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
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
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
Reputation: 14256
Also:
IEnumerable<string> items = Enumerable.Repeat(item, 1).Concat(list);
Upvotes: 3
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
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