C#の配列を内部結合(INNER JOIN)する(LINQ Join)

C#には LINQ というライブラリがあります。

LINQ を使えばコレクション(配列や List クラスなど)に対する処理を簡単に行う事が出来ます。

 

ここでは、LINQ を使って配列を内部結合(INNER JOIN)する方法について解説します。


内部結合(INNER JOIN)とは

内部結合とは別々の配列に格納された要素を1つにまとめて新たな配列を作成する処理です。

 

以下のような配列Aと配列Bがあるとして、特定のフィールド(ここではID)をキーにして同じ値を持つ要素を1つの要素にまとめたデータを作成します。

 

配列A

ID Name
1 A-1_
2 A-2a
2 A-2b
3 A-3_
5 A-5_

配列B

ID Name
1 B-1_
2 B-2a
2 B-2b
3 B-3a
3 B-3b
4 B-4_

 

 

 

 

内部結合結果

ID NameA NameB
1 A-1_ B-1_
2 A-2a B-2a
2 A-2a B-2b
2 A-2b B-2a
2 A-2b B-2b
3 A-3_ B-3a
3 A-3_ B-3b

 

内部結合は結合条件が一致する要素だけを出力します。

(A だけの ID=5 や B だけの ID=4 の要素は出力されない)

キーが重複している場合は全ての組み合わせを出力します。

 

(A, B それぞれに2つある ID=2 は合計4つの組み合わせ全てを出力)


LINQとは

LINQ は IEnumerable<T>インターフェースへの拡張メソッドとして作られています。

つまり、配列Listクラス、Dictionaryクラス、ObservableCollectionクラスなどのIEnumerable<T>インターフェースを実装するオブジェクトであればどれでも同じように使用する事ができます。

 

LINQをつかうには using で System.Linq を参照できるようにしておきましょう。

using System.Linq;

配列を内部結合する Joinメソッド

配列を内部結合するには Join メソッドを使用します。

メソッドの引数は以下のようになっています。

 第1引数 ・・・ 結合するもう1つの配列 (配列B)

 第2引数 ・・・ 結合条件を指定するデリゲート (配列A側)

 第3引数 ・・・ 結合条件を指定するデリゲート (配列B側)

 第4引数 ・・・ 結合結果を作成するデリゲート

 

各引数のデリゲートはラムダ式を使って記述するのが簡単で一般的な方法です。

※ラムダ式の詳細はC#のラムダ式【=>】って何?をご覧ください

            var tableA = new List<TestTable>();
            var tableB = new List<TestTable>();

            tableA.Add(new TestTable() { ID = 1, Name = "A-1_" });
            tableA.Add(new TestTable() { ID = 2, Name = "A-2a" });
            tableA.Add(new TestTable() { ID = 2, Name = "A-2b" });
            tableA.Add(new TestTable() { ID = 3, Name = "A-3_" });
            tableA.Add(new TestTable() { ID = 5, Name = "A-5_" });

            tableB.Add(new TestTable() { ID = 1, Name = "B-1_" });
            tableB.Add(new TestTable() { ID = 2, Name = "B-2a" });
            tableB.Add(new TestTable() { ID = 2, Name = "B-2b" });
            tableB.Add(new TestTable() { ID = 3, Name = "B-3a" });
            tableB.Add(new TestTable() { ID = 3, Name = "B-3b" });
            tableB.Add(new TestTable() { ID = 4, Name = "B-4_" });

            var table = tableA.Join(tableB,
                                    a => a.ID,
                                    b => b.ID,
                                    (a, b) => new {
                                      ID = a.ID,
                                      NameA = a.Name,
                                      NameB = b.Name
                                    });

            foreach (var item in table)
            {
                Console.WriteLine("ID=" + item.ID + " NameA=" + item.NameA + " NameB=" + item.NameB);
            }

tableA に対して Join メソッドを呼び出します。

第1引数に結合相手となる tableB が指定されます。

第2引数のデリゲートには tableA の要素が渡されてくるので キーとする ID の値を返しています。

第3引数のデリゲートには tableB の要素が渡されてくるので キーとする ID の値を返しています。

第3引数のデリゲートには結合する tableA の要素と tableB の要素が渡されてきます。

匿名クラスを使って結合結果となるオブジェクトを作成しています。

 

関連記事