有没有办法在 C# 中的分组列表中查找公共元素?

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" });

结果应该是 {Id = 102, Name = "S2"} 如果我添加

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

结果应该是 {Id = 102, Name = "S2"} {Id = 101, Name = "S1"}

提示:我们可以用 departmentId 分组,并在 3 组中找到共同的 Id。

var groups = lstSource.GroupBy(t1=> t1.departmentId)
                     .ToList();
        var validIds = groups.First().Select(t1 => t1.Id).ToList();
        foreach (var g in groups.Skip(0))
        {
            var otherGroupItemIds = g.Select(t1 => t1.Id).ToList();
            validIds = validIds.Intersect(otherGroupItemIds).ToList();
           
        }
if (validSRIds.Count > 0)
                return lstSource.FindAll(t1 => validSRIds.Contains(t1.Id)).GroupBy(t2 => new { t2.Id, t2.Name }).Select(g => g.First()).OrderByDescending(t => t.Name).ToList();

你会得到属于所有组的所有公共id,name

根据您的评论和上面的示例,我认为与任何给定 Id 关联的 Name 始终相同。在这种情况下,您可以将每个部门注册的 Id 拆分为单独的列表,然后将这些列表相交以找到共同的 Id,然后为每个共同的找到关联的 Name Id.

你在你自己的例子中做了类似的事情。通过重写代码(例如,将 foreach 循环替换为 Aggregate() 函数),您可以获得更直接的方法:

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 为空(不是 null)。

它可以全部写成一个单独的表达式,但我将它分解成几个变量以阐明过程中发生的事情。