2012-07-01 16 views
13

Mam listę ObjA i ObjB następująco:przecinają się dwie listy z różnych przedmiotów

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

Zarówno ObjA i ObjB ma wspólne pole, które jest dla użytkownika i chcę przecinają je na podstawie User.Id.

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

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

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

Jak mogę przecinają te dwie listy na User.Id z LINQ?

W rezultacie chcę tylko listę użytkowników.

Odpowiedz

30

Ogólna idea jest

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

Jednak sama ta zakłada, że ​​User realizuje IEquatable<User>, które nie wydają się być w tym przypadku. Musisz dodać tę implementację lub użyć przeciążenia Intersect akceptującego niestandardowe IEqualityComparer<User>.

+0

A następnie użyj "commonUsers", aby odfiltrować obie listy. – Oded

+0

@Oded: Wydaje się, że to nie jest to, czego szuka. – Jon

+0

Chcę tylko zwykłych użytkowników. – DarthVader

2

Standardowym sposobem jest użycie obiektu IEqualityComparer. Domyślny używa standardowego porównania równości. Utwórz klasę, która implementuje interfejs IEqualityComparer i wykonuje żądane porównanie. Następnie można wywołać przeciążenie IEnumerable.Intersect który akceptuje instancją swoim zwyczajem porównać klasa

7

bez konieczności IEqualityComparer lub IEquatable (co byłoby lepsze w każdym razie)

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

lub

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

1 .Zapoznaj się z tym prostym kodem:

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

2.Kompletny kod

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; } 
} 
Powiązane problemy