2017-01-17 7 views
5

У меня есть N списков «Люди». Люди имеют 2 свойства: Id и Name. Я хочу найти людей, которые содержатся во всех списках N. Я хочу только совместить идентификатор.Найти общие объекты в списках N

Ниже моя отправная точка:

List<People> result = new List<People>(); 

//I think I only need to find items in the first list that are in the others 
foreach (People person in peoplesList.First()) { 

    //then this is the start of iterating through the other full lists 
    foreach (List<People> list in peoplesList.Skip(1)) { 

     //Do I even need this? 

    } 
} 

Я застрял, пытаясь обернуть мою голову вокруг средней части. Мне нужны только те, которые есть в каждом списке от peoplesList.Skip(1).

ответ

4

Математически говоря; вы ищете набор пересечений между всеми вашими списками. К счастью, LINQ имеет метод Instersect, поэтому вы можете итеративно пересекать ваши наборы.

List<List<People>> lists; //Initialize with your data 
IEnumerable<People> commonPeople = lists.First(); 
foreach (List<People> list in lists.Skip(1)) 
{ 
    commonPeople = commonPeople.Intersect(list); 
} 
//commonPeople is now an IEnumerable containing the intersection of all lists 

Чтобы получить «ID» селектор работы вам необходимо будет выполнять IEqualityComparer для People

IEqualityComparer<People> comparer = new PeopleComparer(); 
... 
commonPeople = commonPeople.Intersect(list, comparer); 

Фактическая реализация IEqualityComparer из левой, так как его чертовски просто.

+0

Итак, мы просто продолжаем вносить изменения в существующий список с каждым пересечением. Ницца! Спасибо, я дам этот снимок. –

+1

@DustinBreakey Не новый 'List' (хотя вы * можете * сделать это, просто более неэффективно), новый' IEnumerable', поэтому вы выполняете полный запрос, когда вы повторяете 'commonPeople' на конец. – BradleyDotNET

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