Например:
string element = 'a';
IEnumerable<string> list = new List<string>{ 'b', 'c', 'd' };
IEnumerable<string> singleList = ???; //singleList yields 'a', 'b', 'c', 'd'
Например:
string element = 'a';
IEnumerable<string> list = new List<string>{ 'b', 'c', 'd' };
IEnumerable<string> singleList = ???; //singleList yields 'a', 'b', 'c', 'd'
Я так понимаю, вы не можете просто 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");
Вы можете самостоятельно перевернуть:
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);
public static class IEnumerableExtensions
{
public static IEnumerable<T> Prepend<T>(this IEnumerable<T> ie, T item)
{
return new T[] { item }.Concat(ie);
}
}
Это сделало бы это...
IEnumerable<string> singleList = new[] {element}.Concat(list);
Если вы хотите, чтобы singleList был списком, тогда...
IEnumerable<string> singleList = new List<string>() {element}.Concat(list);
... тоже работает.
также:
IEnumerable<string> items = Enumerable.Repeat(item, 1).Concat(list);
Начиная с .NET Framework 4.7.1 для этого есть метод LINQ:
list.Prepend("a");
https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.prepend?view=netframework-4.7.1
Нет, нет такой встроенной инструкции 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);
Вы даже можете сделать это методом расширения, если допускает версия С#.
Мне удобно иметь возможность добавлять несколько элементов в цепочку. В этой версии используются методы расширения и 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);
Как напоминание - 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> просто для добавления одного элемента (или более одного в одном случае). Это может быть очень дорогостоящей операцией, если ваша коллекция содержит большое количество элементов, а частота добавления - относительно высокая.
Если посмотреть на некоторые из примеров, я думаю, что я бы предпочел изменить расширение для применения к объекту.
public static IEnumerable<T> PrependTo<T>(this T value, IEnumerable<T> values) {
return new[] { value }.Concat(values);
}
Используется как
var singleList = element.PrependTo(list);
Как указано в комментариях Niklas & NetMage.
В С# есть новый встроенный метод Prepend.
В Linq есть стандартный метод Prepend
. Просто пиши
string element = 'a';
IEnumerable<string> list = new List<string>{ 'b', 'c', 'd' };
IEnumerable<string> singleList = list.Prepend(element);