言語
日本語
English

Caution

お使いのブラウザはJavaScriptが無効になっております。
当サイトでは検索などの処理にJavaScriptを使用しています。
より快適にご利用頂くため、JavaScriptを有効にしたうえで当サイトを閲覧することをお勧めいたします。

C#辞典

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

Enumerable.Join() / Zip()

対応: C# 3.0(2007)

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)』のシーケンスを返します。

サンプルコード

Program.cs
using System;
using System.Collections.Generic;
using System.Linq;

// メンバーリストと組織リストを結合します。
var members = new List<(int Id, string Name, int OrgId)>
{
    (1, "孫悟空", 10),
    (2, "ベジータ", 10),
    (3, "クリリン", 20),
};
var orgs = new List<(int Id, string OrgName)>
{
    (10, "カプセルコーポレーション"),
    (20, "亀仙流"),
};

// Join: 組織 ID が一致する行を結合します。
var joined = members.Join(
    orgs,
    m => m.OrgId,
    o => o.Id,
    (m, o) => $"{m.Name} ({o.OrgName})"
);
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}");

// Zip でキャラクターと曲をペアにします。
List<string> songs = new List<string> { "CHA-LA HEAD-CHA-LA", "DAN DAN 心魅かれてく", "魔訶不思議アドベンチャー!" };
var charSongs = names.Zip(songs, (name, song) => $"{name}: {song}");
foreach (var s in charSongs) Console.WriteLine(s);
dotnet script enumerable_join_zip.csx
孫悟空 (カプセルコーポレーション)
ベジータ (カプセルコーポレーション)
クリリン (亀仙流)
孫悟空: 80点
ベジータ: 95点
クリリン: 70点
孫悟空 = 80
ベジータ = 95
クリリン = 70
孫悟空: CHA-LA HEAD-CHA-LA
ベジータ: DAN DAN 心魅かれてく
クリリン: 魔訶不思議アドベンチャー!

概要

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

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

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

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