2014-12-09 10 views
3

Привет У меня есть allLists, который содержит списки строки, я хочу, чтобы найти общие элементы среди этих строк списков я пробовалНайти общие элементы в списке списков строк

var intersection = allLists 
    .Skip(1) 
    .Aggregate(
    new HashSet<string>(allLists.First()), 
    (h, e) => { h.IntersectWith(e); return h);` 

, а также списки пересечений (жесткий код по индекс) все из них не работает, когда я попытался

var inter = allLists[0].Intersect(allLists[1]).Intersect(allLists[2]) 
    .Intersect(allLists[3]).ToList(); 

foreach (string s in inter) Debug.WriteLine(s+"\n "); 

Так как я собираюсь сделать это динамически и получить общие элементы строки в списках; есть ли способ избежать Linq?

+1

Почему вы хотите avoif linq? –

+0

http://stackoverflow.com/a/1132466/4112271 Эта тема похожа на вас ?? –

ответ

0

Я хотел бы сделать это следующим образом:

class Program 
{ 
    static void Main(string[] args) 
    { 
     List<string>[] stringLists = new List<string>[] 
     { 
      new List<string>(){ "a", "b", "c" }, 
      new List<string>(){ "d", "b", "c" }, 
      new List<string>(){ "a", "e", "c" } 
     }; 

     // Will contian only 'c' because it's the only common item in all three groups. 
     var commonItems = 
      stringLists 
      .SelectMany(list => list) 
      .GroupBy(item => item) 
      .Select(group => new { Count = group.Count(), Item = group.Key }) 
      .Where(item => item.Count == stringLists.Length); 

     foreach (var item in commonItems) 
     { 
      Console.WriteLine(String.Format("Item: {0}, Count: {1}", item.Item, item.Count)); 
     } 
     Console.ReadKey(); 
    } 
} 

Элементом является общим пунктом, если это происходит во всех группах, следовательно, при условии, что его счет должен быть равен количеством групп:

.Where(item => item.Count == stringLists.Length) 

EDIT:

я должен был использовать HashSet как в вопросе. Для списков можно заменить SelectMany линию с этим:

.SelectMany(list => list.Distinct()) 
+0

Как использовать forIach commonItems? Я попробовал foreach (строка ss в commonitems), он говорит, что не может преобразовать аноним в строку – kobosh

+0

, каждый элемент в 'commonItems' является анонимным объектом со свойствами' Count' и 'Item', как это определено в' Select'. Я отредактировал ответ и добавил цикл. Вы можете назвать свойства, которые вам нравятся. Это просто пример. – t3chb0t

+0

Это не работает, если элементы могут быть повторены в списках. – Enigmativity

2

Разве это не самый простой способ?

var stringLists = new List<string>[] 
    { 
     new List<string>(){ "a", "b", "c" }, 
     new List<string>(){ "d", "b", "c" }, 
     new List<string>(){ "a", "e", "c" } 
    }; 

var commonElements = 
    stringLists 
     .Aggregate((xs, ys) => xs.Intersect(ys).ToList()); 

получить список с только "c" в нем.

Это также относится к случаю, если элементы в каждом списке можно повторить.

+0

Это может быть короче, но если вам нужно другое условие для 'Intersect', проще сделать это с помощью' GroupBy', чтобы написать пользовательский 'IEqualityComparer' ... тогда это не самый простой способ. – t3chb0t

Смежные вопросы