Caution

お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。

C#辞典

  1. トップページ
  2. C#辞典
  3. Enumerable.Join() / Zip()

Enumerable.Join() / Zip()

2 つのシーケンスを結合する LINQ の拡張メソッドです。共通キーで結合する『Join()』と、位置を合わせてペアにする『Zip()』を解説します。

構文
using System.Linq;

// 共通キーを使って 2 つのシーケンスを内部結合します。
IEnumerable<TResult> joined = outer.Join(
    inner,
    outerKey => 外側のキー,
    innerKey => 内側のキー,
    (outer, inner) => 変換式
);

// 位置を合わせて 2 つのシーケンスをペアにします。
IEnumerable<TResult> zipped = first.Zip(second, (a, b) => 変換式);

// .NET 6 以降: 変換なしでタプルのペアを返す Zip
IEnumerable<(T1, T2)> zipped2 = first.Zip(second);
メソッド一覧
メソッド概要
Join(inner, outerKey, innerKey, result)共通キーが一致する要素を内部結合(INNER JOIN)して変換した結果を返します。
GroupJoin(inner, outerKey, innerKey, result)左外部結合(LEFT OUTER JOIN)に相当するグループ結合を行います。
Zip(second, resultSelector)2 つのシーケンスを位置で対応させてペアを作り、変換した結果を返します。
Zip(second).NET 6 以降。タプル『(T1, T2)』のシーケンスを返します。
サンプルコード
using System;
using System.Collections.Generic;
using System.Linq;

// 社員リストと部署リストを結合します。
var employees = new List<(int Id, string Name, int DeptId)>
{
    (1, "田中", 10),
    (2, "鈴木", 20),
    (3, "佐藤", 10),
};
var departments = new List<(int Id, string DeptName)>
{
    (10, "開発部"),
    (20, "営業部"),
};

// Join: 部署 ID が一致する行を結合します。
var joined = employees.Join(
    departments,
    e => e.DeptId,
    d => d.Id,
    (e, d) => $"{e.Name} ({d.DeptName})"
);
foreach (var s in joined) Console.WriteLine(s);

// Zip: 2 つのリストを位置でペアにします。
List<string> names  = new List<string> { "田中", "鈴木", "佐藤" };
List<int>    scores = new List<int>    { 80, 95, 70 };

var zipped = names.Zip(scores, (name, score) => $"{name}: {score}点");
foreach (var s in zipped) Console.WriteLine(s);

// .NET 6 以降: Zip でタプルを返します。
var pairs = names.Zip(scores);
foreach (var (name, score) in pairs)
    Console.WriteLine($"{name} = {score}");
概要

『Join()』は SQL の INNER JOIN に相当します。外側と内側の両方にキーが存在する場合のみ結果に含まれます。内側シーケンスを事前にハッシュテーブルに展開するため、大規模データでも効率よく結合できます。

『Zip()』は短い方のシーケンスで処理が打ち切られます。長さが異なる場合に警告は出ないため、意図せず要素が欠落することがあります。長さが異なることを意図している場合は問題ありませんが、同じ長さのシーケンスを前提にする場合は事前に長さを確認してください。

外部結合(LEFT JOIN 相当)が必要な場合は『GroupJoin()』と『SelectMany()』を組み合わせます。詳細は『Enumerable.Select() / SelectMany()』を参照してください。グループ化した結合が必要な場合は『Enumerable.GroupBy()』も参考にしてください。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。