【问题标题】:Is there a way to find common elements in grouped lists in c#?有没有办法在 c# 的分组列表中找到常见元素?
【发布时间】:2022-01-18 15:59:32
【问题描述】:
 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。

【问题讨论】:

  • 如果有多个共同元素怎么办?你如何确定一个组?是什么让一件物品与另一件物品“共同”?
  • 你到底在哪里尝试这个?展示自己的努力可能会使问题更清楚。
  • 你到底在哪里尝试这个? - 我想获取所有组中常见的列表,或者可以说是分组(departmentId)项目的交集。
  • 是什么让你无法展示自己的努力?另一个问题完全不同。

标签: c# linq


【解决方案1】:

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

您在自己的示例中做了类似的事情。通过重写代码(例如,将 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)。

这一切都可以写成一个单一的表达式,但我已将其拆分为几个变量以阐明沿途发生的情况。

【讨论】:

    【解决方案2】:
    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、名称

    【讨论】:

    • 是的,两个代码都在工作
    猜你喜欢
    • 2013-02-17
    • 1970-01-01
    • 2017-04-07
    • 1970-01-01
    • 2020-06-16
    • 2020-06-21
    • 2010-12-11
    • 2017-06-14
    • 2018-09-11
    相关资源
    最近更新 更多