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

社会主义新天地 提交于 2020-07-15 06:33:45

问题


For example:

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

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

回答1:


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");



回答2:


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

list.Prepend("a");

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




回答3:


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



回答4:


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);



回答5:


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.




回答6:


Also:

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



回答7:


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);



回答8:


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.




回答9:


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.




回答10:


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);



回答11:


As pointed out by Niklas & NetMage in the comments.

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



来源:https://stackoverflow.com/questions/802537/is-there-a-statement-to-prepend-an-element-t-to-a-ienumerablet

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!