是否有一个声明将元素T添加到IEnumerable <t> </t>

时间:2009-04-29 14:13:24

标签: c# linq

例如:

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

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

11 个答案:

答案 0 :(得分:33)

我认为你不能只Insert进入现有名单吗?

好吧,你可以使用new[] {element}.Concat(list)

否则,您可以编写自己的扩展方法:

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

答案 1 :(得分:5)

你可以自己动手:

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

然后使用它:

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

答案 2 :(得分:5)

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

答案 3 :(得分:3)

这样做......

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

如果你想让singleList成为List,那么......

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

......也有效。

答案 4 :(得分:3)

此外:

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

答案 5 :(得分:3)

自.NET Framework 4.7.1起,存在针对该问题的LINQ方法:

mask-size: cover

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

答案 6 :(得分:1)

不,没有这样的内置声明,声明,但实现这样的功能是微不足道的:

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

如果C#版本允许,您甚至可以将其作为扩展方法。

答案 7 :(得分:1)

我发现能够以可链接的方式添加多个项目很方便。此版本利用了扩展方法和params

作为备注,此版本隐式允许null,但如果这是所需行为,则将其更改为throw new NullReferenceException()同样容易。

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

允许单个项目具有非常易读的语法:

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

...以及项目集合:

GetItems().Prepend(GetMoreItems());

完成问题中的示例会导致:

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

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

答案 8 :(得分:0)

正如提醒一样 - List&lt; T&gt; 不是唯一的容器类型。如果您发现自己经常在列表前面添加元素,您还可以考虑使用 Stack&lt; T&gt; 来实现您的容器。一旦你有一个堆栈

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

你可以随时&#34; prepend&#34;一个元素通过

container.Push("a");

仍然将该集合用作 IEnumerable&lt; T&gt; ,如

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

除了像Pop(),Peek(),...

这样的堆栈的典型其他方法

上面的一些解决方案遍历整个 IEnumeration&lt; T&gt; 只是前置一个元素(或在一个案例中多于一个)。如果您的集合包含大量元素并且预先占用的频率相对较高,则这可能是非常昂贵的操作。

答案 9 :(得分:0)

查看一些示例,我认为我更倾向于将扩展名反转以应用于该对象。

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

一样使用
var singleList = element.PrependTo(list);

答案 10 :(得分:0)

正如Niklas&NetMage在评论中指出的那样。

在C#中有一个新的内置Prepend methond。

enter image description here