Подтвердить что ты не робот

Есть ли инструкция для добавления элемента T в IEnumerable <T>

Например:

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

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

Ответ 1

Я так понимаю, вы не можете просто 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");

Ответ 2

Вы можете самостоятельно перевернуть:

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

Ответ 3

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

Ответ 4

Это сделало бы это...

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

Если вы хотите, чтобы singleList был списком, тогда...

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

... тоже работает.

Ответ 5

также:

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

Ответ 7

Нет, нет такой встроенной инструкции statment, но тривиально реализовать такую ​​функцию:

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

Вы даже можете сделать это методом расширения, если допускает версия С#.

Ответ 8

Мне удобно иметь возможность добавлять несколько элементов в цепочку. В этой версии используются методы расширения и 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);

Ответ 9

Как напоминание - List <T> не единственный тип контейнера. Если вы часто добавляете элементы в начало списка, вы также можете рассмотреть возможность использования Stack <T> для реализации вашего контейнера. Когда у вас есть стек

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

вы всегда можете "добавить" элемент через

container.Push("a");

и по-прежнему использовать коллекцию как IEnumerable <T> как в

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

помимо всех других методов, типичных для стека, таких как Pop(), Peek(),...

Некоторые из вышеперечисленных решений проходят через всю IEnumeration <T> просто для добавления одного элемента (или более одного в одном случае). Это может быть очень дорогостоящей операцией, если ваша коллекция содержит большое количество элементов, а частота добавления - относительно высокая.

Ответ 10

Если посмотреть на некоторые из примеров, я думаю, что я бы предпочел изменить расширение для применения к объекту.

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

Используется как

var singleList = element.PrependTo(list);

Ответ 11

Как указано в комментариях Niklas & NetMage.

В С# есть новый встроенный метод Prepend.

enter image description here

Ответ 12

В Linq есть стандартный метод Prepend. Просто пиши

string element = 'a';
IEnumerable<string> list = new List<string>{ 'b', 'c', 'd' };
IEnumerable<string> singleList = list.Prepend(element);