C# 将两个具有不同对象的列表相交

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11285045/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 17:15:33  来源:igfitidea点击:

intersect two lists with different objects

c#linq

提问by DarthVader

I have a list of ObjA and ObjB as follows:

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

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

Both ObjA and ObjB has a common field which is User and I want to intersect them based on User.Id.

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

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

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

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

How can i intersect these two lists on User.Id with linq?

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

As a result I want only the list of Users.

结果我只想要用户列表。

采纳答案by Jon

The general idea is

一般的想法是

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

However, by itself this assumes that Userimplements IEquatable<User>, which does not seem to be the case here. So you either need to add this implementation or use the Intersectoverload that accepts a custom IEqualityComparer<User>.

但是,这本身就假定了Userimplements IEquatable<User>,而这里似乎并非如此。因此,您要么需要添加此实现,要么使用Intersect接受自定义IEqualityComparer<User>.

回答by rossipedia

The standard way is to utilize an IEqualityComparerobject. The default one uses the standard equality comparison. Create a class that implements the IEqualityComparerinterface and performs the comparison you want. Then you can call an overload of IEnumerable.Intersectthat accepts an instance of your custom compare class

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

回答by Rapha?l Althaus

without need of IEqualityComparer or IEquatable (which would be better anyway)

不需要 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));

or

或者

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

回答by anuo

1.look at this simple code

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.complete code

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