いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

Linq入門記-29 (LINQ To Object, Join)


今回は、Join拡張メソッドについてです。


Join拡張メソッドは、クエリ式での「join xx in xx on xx equals xx」に対応する拡張メソッドです。
LINQでの結合については、以前の記事で記述していますので、そちらを参照下さればと思います。


Join拡張メソッドの書式は以下の通りです。

public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(
    this IEnumerable<TOuter> outer,
    IEnumerable<TInner> inner,
    Func<TOuter, TKey> outerKeySelector,
    Func<TInner, TKey> innerKeySelector,
    Func<TOuter, TInner, TResult> resultSelector
)

public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(
    this IEnumerable<TOuter> outer,
    IEnumerable<TInner> inner,
    Func<TOuter, TKey> outerKeySelector,
    Func<TInner, TKey> innerKeySelector,
    Func<TOuter, TInner, TResult> resultSelector,
    IEqualityComparer<TKey> comparer
)


一つ目の書式が一番よく利用される形のものですね。
2つめの書式は、一つ目の分にIEqualityComparer comparerが追加されています。
キーの同値性を独自の方法で決定する際に利用します。


引数が多いですが、慣れるとそんなに難しくありません。
クエリ式で

from   team   in teams
join   person in people on team equals person.Team
select new { team, person }


という記述は、

team.Join(people, team => team, person => person.Team, (team, person) => new { team, person })


となります。


以下、サンプルです。

    #region LinqSamples-26
    public class LinqSamples26 : IExecutable
    {
        class Person
        {
            public string Name { get; set; }
            public Team   Team { get; set; }
        }
        
        class Team
        {
            public string Name { get; set; }
        }
        
        public void Execute()
        {
            var t1 = new Team { Name = "Team 1" };
            var t2 = new Team { Name = "Team 2" };
            
            var p1 = new Person { Name = "gsf_zero1", Team = t1 };
            var p2 = new Person { Name = "gsf_zero2", Team = t2 };
            var p3 = new Person { Name = "gsf_zero3", Team = t1 };
            
            var teams  = new List<Team>   { t1, t2 };
            var people = new List<Person> { p1, p2, p3 };
            
            //
            // 結合する.
            //
            // 以下のクエリ式と同じ事となる。
            //
            //     from   team   in teams
            //     join   person in people on team equals person.Team
            //     select new { TeamName = team.Name, PersonName = person.Name }
            //
            var query = 
                    teams.Join                 // TOuter
                    (
                        people,                // TInner
                        team   => team,        // TOuterのキー
                        person => person.Team, // TInnerのキー
                        (team, person) =>      // 結果
                            new { TeamName = team.Name, PersonName = person.Name }
                    );
            
            foreach (var item in query)
            {
                Console.WriteLine("Team = {0}, Person = {1}", item.TeamName, item.PersonName);
            }
        }
    }
    #endregion


実行結果は以下の通りです。

  Team = Team 1, Person = gsf_zero1
  Team = Team 1, Person = gsf_zero3
  Team = Team 2, Person = gsf_zero2

================================
過去の記事については、以下のページからご参照下さい。