プログラマーな日々

I'm a Cloud Architect and Developer. And I'm highly motivated to reduce toils with driving DevOps.

IEnumerable.GroupJoinメソッド

Enumerable.GroupJoin(TOuter, TInner, TKey, TResult) メソッド (IEnumerable(TOuter), IEnumerable(TInner), Func(TOuter, TKey), Func(TInner, TKey), Func(TOuter, IEnumerable(TInner), TResult)) (System.Linq)
キーが等しいかどうかに基づいて 2 つのシーケンスの要素を相互に関連付け、その結果をグループ化します。 キーの比較には既定の等値比較子が使用されます。

SQLでは、LEFT OUTER JOINまたはRIGHT OUTER JOINに相当します。

ソースコード

using System;
using System.Linq;

namespace LinqSample {
    class Program {
        static void Main(string[] args) {
            Man[] mans = new Man[] { 
                new Man() { Name = "suzuki taro", PetName = "horse" },
                new Man() { Name = "suzuki jiro", PetName = null },
                new Man() { Name = "sato taro", PetName = "cat" },
                new Man() { Name = "sato jiro", PetName = "dog" }
            };

            Pet[] pets = new Pet[] {
                new Pet() { Name = "dog", Food = "meat" },
                new Pet() { Name = "cat", Food = "fish" },
                new Pet() { Name = "horse", Food = "grass" }
            };

            var q = mans.GroupJoin(
                pets, 
                man => man.PetName, // JOINのキー
                pet => pet.Name,    // JOINのキー
                (man, pet) => new { ManName = man.Name, Pets = pet.DefaultIfEmpty() })
            // シーケンスの展開
            .SelectMany(o => o.Pets, (o, p) => new {
                ManName = o.ManName,
                PetName = p == null ? "Null" : p.Name,
                Food = p == null ? "Null" : p.Food
            });

            foreach (var o in q) {
                Console.WriteLine("Man = {0}, Pet = {1}, Food = {2}", o.ManName, o.PetName, o.Food);
            }
            Console.ReadKey();
        }
    }

    class Man {
        public string Name { get; set; }
        public string PetName { get; set; }
    }

    class Pet {
        public string Name { get; set; }
        public string Food { get; set; }
    }
}

実行結果