【C#】LINQのIntersectメソッドで2つのリストの共通要素(積集合)を抽出する

2つのデータセットを比較し、「両方に含まれているデータ」だけを取り出したい場合があります。これを数学的な用語で「積集合(Intersection)」と呼びます。

C#のLINQには、この操作を直感的に行えるIntersectメソッドが用意されています。今回は、採用システムにおける「募集要項の必須スキル」と「応募者の保有スキル」を照合し、合致しているスキルを抽出するシナリオを例に解説します。


目次

Intersectメソッドの概要

Intersectメソッドは、2つのシーケンス(配列やリスト)を比較し、両方のシーケンスに存在する要素のみを含む新しいシーケンスを返します。

主な特徴は以下の通りです。

  1. 共通項の抽出: 片方のリストにしか存在しない要素は除外されます。
  2. 結果の一意性: 元のリストに同じ値が複数含まれていても、結果のリストでは重複が削除され、各要素は1回だけ出現します。

実践的なコード例:スキルのマッチング機能

以下のコードは、企業が求めるスキルセットと、応募者が持っているスキルセットを比較し、マッチしたスキルをリストアップする例です。

using System;
using System.Collections.Generic;
using System.Linq;

namespace SkillMatchingSystem
{
    class Program
    {
        static void Main()
        {
            // シナリオ:
            // 採用選考において、募集要項の必須スキルと応募者のスキルを比較する。
            // 両方のリストに含まれる「マッチしたスキル」を特定したい。

            // 募集要項にある必須スキルリスト
            var requiredSkills = new[] 
            { 
                "C#", 
                "SQL Server", 
                "Azure", 
                "Docker",
                "C#" // リスト作成ミスで重複があってもIntersectが解決します
            };

            // 応募者の保有スキルリスト
            var applicantSkills = new[] 
            { 
                "Java", 
                "C#", 
                "Python", 
                "Docker", 
                "Linux" 
            };

            // 1. Intersectを使用して積集合(共通するスキル)を取得
            // requiredSkills と applicantSkills の両方に含まれる文字列のみが抽出されます。
            IEnumerable<string> matchedSkills = requiredSkills.Intersect(applicantSkills);

            // 結果の出力
            Console.WriteLine("--- マッチしたスキル ---");
            if (matchedSkills.Any())
            {
                Console.WriteLine(string.Join(", ", matchedSkills));
            }
            else
            {
                Console.WriteLine("マッチするスキルはありませんでした。");
            }
        }
    }
}

実行結果

--- マッチしたスキル ---
C#, Docker

技術的なポイントと注意点

1. 比較の仕組みとカスタム比較

デフォルトでは、要素の型(上記の例ではstring)の既定の比較ロジック(Default等価比較子)が使用されます。文字列の場合、大文字と小文字は区別されます。もし「docker」と「Docker」を同一視してマッチングさせたい場合は、Intersectの第2引数にIEqualityComparer<T>を渡す必要があります。

// 大文字小文字を無視して比較する場合
var matchedSkillsIgnoreCase = requiredSkills.Intersect(
    applicantSkills, 
    StringComparer.OrdinalIgnoreCase
);

2. パフォーマンスと遅延実行

Intersectメソッドは遅延実行(Deferred Execution)されます。実際に比較処理が走るのは、結果をforeachで回したり、ToList()などを呼び出した時点です。内部的にはセットベースのアプローチ(ハッシュセット等)を使用するため、比較的大きなコレクション同士の比較でも効率的に動作します。

3. 重複の排除

入力元のリスト(例:requiredSkills)に重複データが含まれていたとしても、Intersectの結果は数学的な集合の定義に従い、重複のない一意なリストとなります。このため、事前のDistinct呼び出しは不要です。

まとめ

Intersectメソッドを使用することで、ループ処理や条件分岐を複雑に組み合わせることなく、シンプルに「共通項」を抽出できます。データ照合やフィルタリング機能の実装において、可読性を高めるために非常に有効な手段です。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次