简体   繁体   中英

intersect two lists with different objects

I have a list of ObjA and ObjB as follows:

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.

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?

As a result I want only the list of Users.

The general idea is

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

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

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

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

1.look at this simple code

  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

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

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

You can use the extension method Linq

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

For more information , you can visite https://www.tutorialsteacher.com/linq/linq-joining-operator-join

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM