【问题标题】:intersect two lists with different objects将两个具有不同对象的列表相交
【发布时间】:2012-07-01 19:36:26
【问题描述】:

我有一个 ObjA 和 ObjB 的列表如下:

List<ObjA> List1;
List<ObjB> List2;

ObjA 和 ObjB 都有一个公共字段,即 User,我想根据 User.Id 将它们相交。

class ObjA
{ 
  User user;
  .... other properties
}

class ObjB
{ 
  User user;
  .... other properties
}

class User
{
    int Id;
     .... other props
}

如何将 User.Id 上的这两个列表与 linq 相交?

因此我只想要用户列表。

【问题讨论】:

    标签: c# linq


    【解决方案1】:

    总体思路是

    var commonUsers = list1.Select(a => a.User).Intersect(list2.Select(b => b.User));
    

    但是,这本身假设 User 实现了 IEquatable&lt;User&gt;,这似乎不是这里的情况。因此,您要么需要添加此实现,要么使用接受自定义 IEqualityComparer&lt;User&gt;Intersect 重载。

    【讨论】:

    • 然后使用commonUsers过滤两个列表。
    • @Oded:这似乎不是他想要的。
    • 如果您确实想要来自一个(或两个)列表的结果,而不仅仅是 commonUsers,则加入效果很好。见stackoverflow.com/a/5468803/329301
    【解决方案2】:

    1.看看这个简单的代码

      var result = (from objA in objAList
                    join objB in objBList on objA.user.Id equals objB.user.Id
                    select objA/*or objB*/).ToList();
    

    2.完整代码

     class QueryJoin
    {
        static void Main(string[] args)
        {
            //create users
            User user1 = new User { Id = 1, Name = "anuo1" };
            User user2 = new User { Id = 2, Name = "anuo2" };
            User user3 = new User { Id = 3, Name = "anuo3" };
            User user4 = new User { Id = 4, Name = "anuo4" };
            User user5 = new User { Id = 5, Name = "anuo5" };
            //create objAList
            List<ObjA> objAList = new List<ObjA>();
            objAList.Add(new ObjA { user = user1 });
            objAList.Add(new ObjA { user = user2 });
            objAList.Add(new ObjA { user = user3 });
            //create objBList
            List<ObjB> objBList = new List<ObjB>();
            objBList.Add(new ObjB { user = user3 });
            objBList.Add(new ObjB { user = user4 });
            objBList.Add(new ObjB { user = user5 });
    
            //intersect
            var result = (from objA in objAList
                          join objB in objBList on objA.user.Id equals objB.user.Id
                          select objA/*or objB*/).ToList();
    
        }
    
    }
    
    class ObjA
    {
        public User user { get; set; }
    }
    
    class ObjB
    {
        public User user { get; set; }
    }
    
    class User
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
    

    【讨论】:

      【解决方案3】:

      不需要 IEqualityComparer 或 IEquatable(反正会更好)

      var commonUsers = list1
                        .Select(l1 => l1.User)
                        .Where(u => list1
                             .Select(l => l.User.Id)
                             .Intersect(list2
                                .Select(l2 => l2.Id))
                             .Contains(u.Id));
      

      var commonUsers = list1.Select(l1 => l1.User)
                            .Where(u=> list2.Select(l2 => l2.User.Id)
                                              .Contains(u.Id));
      

      【讨论】:

        【解决方案4】:

        标准方法是使用IEqualityComparer 对象。默认使用标准相等比较。创建一个实现IEqualityComparer 接口并执行所需比较的类。然后您可以调用IEnumerable.Intersect 的重载,它接受您的自定义比较类的实例

        【讨论】:

          【解决方案5】:

          可以使用扩展方法Linq

          var result = List1.Join(List2, e1 =&gt; e1.ID, e2 =&gt; e2.ID, (e1, e2)=&gt; e1);

          更多信息,您可以访问https://www.tutorialsteacher.com/linq/linq-joining-operator-join

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-06-16
            • 1970-01-01
            • 1970-01-01
            • 2012-02-12
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多