'Is there a way to find common elements in grouped lists in c#?

 List<empl> lstSource = new List<empl>();

        lstSource.Add(new empl { departmentId = 2, Id = 101, Name = "S1" }); 
        lstSource.Add(new empl { departmentId = 2, Id = 109, Name = "S9" });
        lstSource.Add(new empl { departmentId = 2, Id = 102, Name = "S2" });
        

        lstSource.Add(new empl { departmentId = 4, Id = 101, Name = "S1" });
        lstSource.Add(new empl { departmentId = 4, Id = 102, Name = "S2" });
        lstSource.Add(new empl { departmentId = 4, Id = 108, Name = "S8" });

        lstSource.Add(new empl { departmentId = 3, Id = 105, Name = "S5" });
        lstSource.Add(new empl { departmentId = 3, Id = 103, Name = "S3" });
        lstSource.Add(new empl { departmentId = 3, Id = 102, Name = "S2" });

should result {Id = 102, Name = "S2"} if I add

lstSource.Add(new empl { departmentId = 3, Id = 101, Name = "S1" }); 

should result {Id = 102, Name = "S2"} {Id = 101, Name = "S1"}

Hint : we can group with departmentId and find common Id in 3 group.



Solution 1:[1]

Based on your comments and example above, I take it that the Name associated with any given Id is always the same. In that case, you could split the Ids registered on each department into separate lists, then intersect those lists to find the common Ids, and then find the associated Name for each common Id.

You have done something similar in your own example. By rewriting the code (e.g. by replacing the foreach loop with an Aggregate() function) you could achieve a more straight forward approach:

var idsPerDepartment = lstSource
    .GroupBy(item => item.departmentId)
    .Select(gr => gr.Select(item => item.Id));

var commonIds = idsPerDepartment
    .Aggregate((common, next) => common.Intersect(next));

var commonItems = commonIds
    .Select(id => lstSource.First(item => item.Id == id))
    .Select(commonItem => new { commonItem.Id, commonItem.Name })
    .OrderByDescending(commonItem => commonItem.Name);

commonItems is empty (not null) if there are no common items.

It could all be written as one single expression, but I've spilt it into several variables to clarify what is happening along the way.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Astrid E.