Объединение списков в Lambda /LINQ
Вопрос
Если у меня есть переменная типа IEnumerable<List<string>>
есть ли оператор LINQ или лямбда-выражение, которое я могу применить к нему, которое объединит списки, возвращающие IEnumerable<string>
?
Решение
SelectMany - т. е.
IEnumerable<List<string>> someList = ...;
IEnumerable<string> all = someList.SelectMany(x => x);
Для каждого элемента в someList затем используется лямбда "x => x", чтобы получить IEnumerable<T> для внутренних элементов.В этом случае каждый "x" представляет собой список<T>, который уже является IEnumerable<T>.
Затем они возвращаются в виде непрерывного блока.По сути, SelectMany - это что-то вроде (упрощенное):
static IEnumerable<TResult> SelectMany<TSource, TResult>(
this IEnumerable<TSource> source,
Func<TSource, IEnumerable<TResult>> selector) {
foreach(TSource item in source) {
foreach(TResult result in selector(item)) {
yield return result;
}
}
}
Хотя это несколько упрощено.
Другие советы
Как насчет
myStrings.SelectMany(x => x)
Не совсем один вызов метода, но вы должны быть в состоянии написать
var concatenated = from list in lists from item in list select item;
Где "списки" - это ваш IEnumerable<List<string>>
и объединенный имеет тип IEnumerable<string>
.
(Технически это является один вызов метода для SelectMany
- просто не похоже, что это было все, что я имел в виду во вступительном слове.Просто хотел прояснить это на случай, если кто-то запутается или прокомментирует - я понял после того, как опубликовал, как это могло быть прочитано).
Сделайте это простым способом.Нет необходимости в LINQ:
IEnumerable<string> GetStrings(IEnumerable<List<string>> lists)
{
foreach (List<string> list in lists)
foreach (string item in list)
{
yield return item;
}
}
Используя выражение LINQ...
IEnumerable<string> myList = from a in (from b in myBigList
select b)
select a;
...работает просто отлично.:-)
b
будет представлять собой IEnumerable<string>
и a
будет представлять собой string
.
Вот еще одно понимание запроса LINQ.
IEnumerable<string> myStrings =
from a in mySource
from b in a
select b;