2012-07-01 16 views
13

次のように私はOBJAとObjBのリストを持っている:2交差リスト

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

両方OBJAとObjBは、ユーザーである一般的なフィールドを持っていると私はUser.Id.に基づいてそれらを交差するようにしたいです

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

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

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

これらの2つのリストをUser.Idでlinqとどのように交差させることができますか?

結果として、私はユーザーの一覧だけを必要とします。

答えて

30

一般的な考え方は、

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

であるが、それ自体でこれはUserがここケースではないようですIEquatable<User>を実装していることを前提としています。したがって、この実装を追加するか、カスタムIEqualityComparer<User>を受け入れるIntersectオーバーロードを使用する必要があります。

+0

そして、 'commonUsers'を使って両方のリストをフィルタリングしてください。 – Oded

+0

@Oded:彼は後になっているようではありません。 – Jon

+0

私はただの共通のユーザーがほしい。 – DarthVader

2

標準的な方法は、IEqualityComparerオブジェクトを利用することです。デフォルトのものは標準的な等価比較を使用します。 IEqualityComparerインターフェイスを実装し、必要な比較を実行するクラスを作成します。そして、あなたは(とにかく方が良いと思われる)されたIEqualityComparerまたはIEquatableを必要とせずにクラス

7

を比較

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

1カスタムのインスタンスを受け入れるIEnumerable.Intersectのオーバーロードを呼び出すことができます。この簡単なコードで見てください

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