2014-02-10 5 views
2

У меня есть List(Of HashSet(Of String)). Есть ли явный однолинейный способ LINQ для получения единственного HashSet(Of String), содержащего все строки в значениях ввода списка?Как я могу объединить IEnumerable (из IEnumerable) с помощью LINQ?

Например, из трех хэш-наборов {"A"}, {"A", "B", "C"} и {"B", "C", "D"} Я бы хотел одиночный хэш («A», «B», «C», «D»}.

Я уверен, что смогу что-то сделать с .Aggregate() или .Accumulate().

Взаимодействие C# или VB.NET одинаково полезно.

+0

'SelectMany' .. –

ответ

7

Вы можете использовать только SelectMany. В C#:

var newHashSet = new HashSet<string>(myListOfHashSets.SelectMany(x => x)); 

И в VB.NET:

Dim newHashSet As New HashSet(Of String)(myListOfHashSets.SelectMany(Function (x) x)) 
+3

@CSharpie Не требуется. «Distinct» по существу создает хеш-набор, затем перечисляет его, поэтому простое выделение в новый хэш-набор сохраняет один шаг. –

+0

Это не возвращает отдельный список, как требуется в вопросе. Добавьте вызов в «Различный». – Crono

+0

@ p.s.w.g сладкий я даже не подумал об этом. Изучайте материал каждый день ... – CSharpie

2

SelectMany делает именно это. На высоком уровне (опуская дженерики и упрощающего немного), SelectMany реализуется как:

static IEnumerable SelectMany(this source, Func selector) 
{ 
    IEnumerable results; 
    foreach (var item in source) 
    { 
     foreach (var result in selector(item)) 
     { 
      results.add(result); 
     } 
    } 
    return results; 
} 

Приведенный выше код на самом деле не точны; вместо этого он использует возврат доходности для выполнения выбора лениво и не использует промежуточную коллекцию results. Наконец, полная подпись на самом деле public static IEnumerable<TResult> SelectMany<TSource, TResult>( this IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> selector), но единственной важной частью, которую нужно понять, является то, что селектор возвращает коллекцию. Если у вас есть коллекция коллекций, то использование функции идентификации x => x делает именно это.

Таким образом, он сглаживает коллекции коллекций в одну коллекцию. Использование функции идентификации x => x в качестве селектора означает, что элементы внутренних коллекций не изменяются. Так что, как некоторые другие выложили, окончательный ответ будет:

var newSet = new HashSet(setOfSets.SelectMany(element => element)); 
1

Вы можете попробовать использовать метод UnionWith из HashSet. Это будет что-то вроде этого:

var result = myListOfHashSets.Aggregate(new HashSet<string>(), (x, y) => { x.UnionWith(y); return x; }); 
Смежные вопросы