Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【PHP8.x】array_intersect()関数の使い方

array_intersect関数の使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

array_intersect関数は、複数の配列の中から、すべての配列に共通して存在する値を見つけ出し、新しい配列として返す機能を提供する関数です。この関数はPHPのバージョン8.4で利用できます。

具体的には、最初の配列を基準として、それ以降に指定されたすべての配列に存在する値を検索します。値の比較は、厳密な型比較ではなく、PHPの標準的な比較規則(==演算子に準ずる)に基づいて行われます。例えば、整数5と文字列"5"は等しいと判断される場合があります。この関数は、配列のキーではなく、あくまで値に基づいて共通部分を特定します。

引数には、比較対象となる配列を複数指定します。最低2つの配列が必要です。戻り値としては、すべての配列に共通して含まれる値だけを集めた新しい配列が返されます。この新しい配列のキーは、共通する値が最初の配列で持っていたキーがそのまま保持されます。もし共通する値が一つも存在しない場合は、空の配列が返されます。

この関数は、複数のデータセットから共通の要素を抽出する際に非常に役立ちます。例えば、異なるユーザーグループに共通して存在するアイテムをリストアップしたい場合などに使用できます。キーは比較の対象外であるため、キーも含めて比較したい場合は、関連する別の関数を使用する必要があります。

構文(syntax)

1<?php
2$array1 = ['a' => 'green', 'red', 'blue'];
3$array2 = ['b' => 'green', 'yellow', 'red'];
4$result = array_intersect($array1, $array2);
5print_r($result);
6?>

引数(parameters)

array $array, array ...$arrays

  • array $array: 比較対象となる配列
  • array ...$arrays: 比較対象となる追加の配列(可変長引数)

戻り値(return)

array

与えられた配列の全てに存在する値のみを抽出した新しい配列を返します。

サンプルコード

PHP: 大文字小文字を区別しない共通配列要素の抽出

1<?php
2
3/**
4 * 複数の配列間で大文字小文字を区別しない共通要素の抽出を行います。
5 *
6 * この関数は、入力されたすべての配列の文字列値を小文字に変換してから、
7 * array_intersect() 関数を使用して共通の要素を検索します。
8 * これにより、例えば 'Apple' と 'apple' は同じ要素として扱われます。
9 *
10 * @param array $array1 比較対象の最初の配列。
11 * @param array ...$arrays 比較対象の追加配列。
12 * @return array すべての入力配列に共通して存在する要素の配列(値は小文字に変換されています)。
13 *               返される配列のキーは、最初の配列 ($array1) のキーが保持されますが、
14 *               値は小文字に変換されたものです。
15 */
16function array_intersect_case_insensitive(array $array1, array ...$arrays): array
17{
18    // 配列のすべての文字列要素を小文字に変換するクロージャ
19    $toLower = function(array $arr): array {
20        return array_map(function($value) {
21            // 文字列である場合のみ小文字に変換し、他の型はそのまま保持する
22            return is_string($value) ? strtolower($value) : $value;
23        }, $arr);
24    };
25
26    // 最初の配列の要素を小文字に変換
27    $lowerArray1 = $toLower($array1);
28
29    // その他のすべての配列の要素を小文字に変換
30    // array_map を使用して、各追加配列に $toLower クロージャを適用
31    $lowerAdditionalArrays = array_map($toLower, $arrays);
32
33    // 変換されたすべての配列を1つのリストに結合
34    // array_intersect() の引数として渡すために、最初の配列を先頭に追加
35    $allLowerArrays = array_merge([$lowerArray1], $lowerAdditionalArrays);
36
37    // 結合された配列リストを array_intersect() に動的に引数として渡す
38    // call_user_func_array は、配列の要素を関数の個別の引数として渡すために使用される
39    return call_user_func_array('array_intersect', $allLowerArrays);
40}
41
42// --- 使用例 ---
43
44$fruits1 = ['Apple', 'Banana', 'Orange', 'Grape'];
45$fruits2 = ['apple', 'banana', 'Kiwi', 'Mango'];
46$fruits3 = ['APPLE', 'BANANA', 'Pineapple'];
47
48echo "--- 元の配列 --- \n";
49echo "配列1: " . implode(', ', $fruits1) . "\n";
50echo "配列2: " . implode(', ', $fruits2) . "\n";
51echo "配列3: " . implode(', ', $fruits3) . "\n\n";
52
53// 大文字小文字を区別しない共通要素の検索
54$commonFruits = array_intersect_case_insensitive($fruits1, $fruits2, $fruits3);
55
56echo "--- 大文字小文字を区別しない共通要素 --- \n";
57print_r($commonFruits);
58/*
59期待される出力例:
60Array
61(
62    [0] => apple
63    [1] => banana
64)
65*/
66
67echo "\n--- 数字を含む別の例 --- \n";
68
69$data1 = ['Alpha', 123, 'Beta', 'Gamma'];
70$data2 = ['alpha', 123, 'Delta', 'beta'];
71$data3 = ['ALPHA', 456, 'BETA'];
72
73echo "データ1: "; print_r($data1);
74echo "データ2: "; print_r($data2);
75echo "データ3: "; print_r($data3);
76
77$commonData = array_intersect_case_insensitive($data1, $data2, $data3);
78
79echo "\n--- 大文字小文字を区別しない共通データ --- \n";
80print_r($commonData);
81/*
82期待される出力例:
83Array
84(
85    [0] => alpha
86    [1] => 123
87)
88*/

PHPのarray_intersect関数は、複数の配列から共通して存在する値のみを抽出し、新しい配列として返す機能を提供します。しかし、この関数はデフォルトで大文字と小文字を区別するため、「Apple」と「apple」のような値は異なるものとして扱われます。

提供されたサンプルコードのarray_intersect_case_insensitive関数は、この挙動を拡張し、大文字と小文字を区別せずに共通要素を抽出できるようにするものです。この関数は、比較対象となるすべての配列の文字列要素を内部的に小文字に変換してから、元のarray_intersect関数に渡して共通の要素を検索します。これにより、入力された「Apple」「apple」「APPLE」といった異なる表記の文字列も同じ要素と見なされ、共通要素として抽出されます。

引数には、共通要素を抽出したい複数の配列を指定します。戻り値としては、すべての入力配列に共通して存在する要素を含む新しい配列が返されます。このとき、返される配列の文字列要素はすべて小文字に変換された状態となります。数字などの文字列以外の型は、共通要素として扱われる場合はその値がそのまま保持されます。この関数は、柔軟な条件で配列間の共通点を見つけたい場合に非常に役立ちます。

この関数は、複数の配列から大文字小文字を区別せずに共通の文字列要素を抽出しますが、戻り値の文字列はすべて小文字に変換されます。そのため、元の配列の大文字小文字の情報を保持したい場合は、別途処理が必要です。数値などの非文字列要素は、小文字に変換されずそのままの値で比較されます。また、結果として返される配列のキーは、比較対象の最初の配列のキーが維持される点にご留意ください。大量のデータを扱う際には、すべての文字列を小文字に変換する処理が内部で行われるため、パフォーマンスへの影響を考慮することが重要です。

PHP array_intersect_keyで共通キー配列を抽出する

1<?php
2
3/**
4 * 複数の配列に共通して存在するキーを持つ要素を抽出します。
5 *
6 * この関数は、最初の配列を基準とし、そのキーが他のすべての配列にも存在する場合に、
7 * 最初の配列から対応するキーと値を返します。
8 * キーのみが比較され、値は比較されません。
9 *
10 * @param array $array1 比較の基準となる最初の配列。
11 * @param array ...$arrays 比較対象となる1つ以上の追加の配列。
12 * @return array 共通のキーを持つ要素からなる配列。
13 */
14function demonstrateArrayIntersectKey(array $array1, array ...$arrays): array
15{
16    // array_intersect_keyは、指定されたすべての配列に存在するキーを持つ要素を返します。
17    // 値は比較せず、キーのみを比較します。
18    // 最初の配列の値が結果として保持されます。
19    return array_intersect_key($array1, ...$arrays);
20}
21
22// 使用例:
23$baseArray = [
24    'id' => 101,
25    'name' => 'Alice',
26    'email' => 'alice@example.com',
27    'status' => 'active'
28];
29
30$filterArray1 = [
31    'id' => 200, // キーは存在するが値は異なる
32    'name' => 'Bob',
33    'created_at' => '2023-01-01'
34];
35
36$filterArray2 = [
37    'name' => 'Charlie',
38    'email' => 'charlie@example.com',
39    'updated_at' => '2023-05-01'
40];
41
42// baseArrayとfilterArray1、filterArray2の全てに共通するキーの要素を抽出
43$commonKeysResult = demonstrateArrayIntersectKey($baseArray, $filterArray1, $filterArray2);
44
45echo "元の配列1 (基準): \n";
46print_r($baseArray);
47
48echo "元の配列2: \n";
49print_r($filterArray1);
50
51echo "元の配列3: \n";
52print_r($filterArray2);
53
54echo "すべての配列に共通するキーを持つ要素:\n";
55print_r($commonKeysResult);
56
57// 期待される出力:
58// 'name' はすべての配列に存在するキーなので、$baseArray['name'] が結果に含まれる。
59// 'id' は $baseArray と $filterArray1 に存在するが、$filterArray2 には存在しないため、結果には含まれない。
60// 'email' は $baseArray と $filterArray2 に存在するが、$filterArray1 には存在しないため、結果には含まれない。
61// 結果: Array ( [name] => Alice )
62
63// 別の使用例:
64$products = [
65    'apple' => ['price' => 100, 'stock' => 50],
66    'banana' => ['price' => 50, 'stock' => 100],
67    'orange' => ['price' => 80, 'stock' => 70]
68];
69
70$availableProducts = [
71    'apple' => true,
72    'banana' => true,
73    'grape' => true
74];
75
76$onSaleProducts = [
77    'banana' => true,
78    'orange' => true,
79    'kiwi' => true
80];
81
82// products, availableProducts, onSaleProductsの全てに共通するキーを持つ要素を抽出
83$filteredProducts = demonstrateArrayIntersectKey($products, $availableProducts, $onSaleProducts);
84
85echo "\n元の商品リスト:\n";
86print_r($products);
87
88echo "利用可能な商品 (キーのみ比較):\n";
89print_r($availableProducts);
90
91echo "セール中の商品 (キーのみ比較):\n";
92print_r($onSaleProducts);
93
94echo "利用可能かつセール中の商品(元の商品の情報):\n";
95print_r($filteredProducts);
96
97// 期待される出力:
98// 'banana' がすべての配列に共通するキーなので、$products['banana'] が結果に含まれる。
99// 結果: Array ( [banana] => Array ( [price] => 50 [stock] => 100 ) )
100
101?>

PHP 8で提供されるarray_intersect_key関数は、複数の配列に共通して存在するキーを持つ要素を抽出するために使用されます。この関数は、最初の配列を基準として、その配列のキーが比較対象となる他のすべての配列にも存在するかどうかを確認します。値そのものは比較せず、キーの名前のみを比較の対象とします。

引数としては、まず比較の基準となる最初の配列を一つ指定します。続いて、比較対象となる追加の配列を複数指定することができます。関数が実行されると、すべての配列に共通して存在するキーを持つ要素が、基準となる最初の配列から抽出されて新しい配列として返されます。したがって、結果として得られる配列には、共通するキーに対応する最初の配列の値が保持されます。例えば、異なる設定ファイルから共通のキーを持つ設定項目を抽出するような場面で、この関数は非常に役立ちます。

この関数は、複数の配列間でキーのみを比較し、それらすべての配列に共通して存在するキーを持つ要素を抽出します。最も重要な注意点は、値は一切比較されないことです。共通のキーが見つかった場合、基準となる最初の配列のキーと値が結果として返されます。キーは一致しても、値が異なっていても結果には影響しません。可変長引数により、複数の配列を同時に比較できます。元の配列は変更されず、共通のキーを持つ要素だけを含む新しい配列が戻り値として生成されますので、コードを安全に利用できます。主に連想配列のキーを比較したい場合に役立ちます。

PHP array_intersect で多次元配列を比較する

1<?php
2
3/**
4 * 多次元配列を一次元配列に平坦化します。
5 * array_intersect 関数は一次元配列の値を比較するため、
6 * 多次元配列内の共通の値を効率的に見つけるためにこのヘルパー関数を使用します。
7 *
8 * @param array $array 平坦化する多次元配列
9 * @return array 平坦化された一次元配列
10 */
11function flattenMultidimensionalArray(array $array): array
12{
13    $result = [];
14    foreach ($array as $element) {
15        if (is_array($element)) {
16            // 要素が配列の場合、再帰的に平坦化して結果に結合
17            $result = array_merge($result, flattenMultidimensionalArray($element));
18        } else {
19            // 要素が配列でない場合、直接結果に追加
20            $result[] = $element;
21        }
22    }
23    return $result;
24}
25
26// サンプルデータとして、複数の多次元配列を定義します。
27// これらの配列内の共通の値を見つけることを目的とします。
28$multiArray1 = [
29    'user_info' => ['id' => 101, 'roles' => ['admin', 'editor'], 'tags' => ['php', 'web']],
30    'products' => ['apple', 'banana', 'orange'],
31    'settings' => ['theme' => 'dark', 'language' => 'en']
32];
33
34$multiArray2 = [
35    'customer_details' => ['id' => 201, 'permissions' => ['write', 'read'], 'tags' => ['php', 'cloud']],
36    'products' => ['banana', 'grape', 'apple'],
37    'preferences' => ['color' => 'blue', 'language' => 'en']
38];
39
40$multiArray3 = [
41    'group_data' => ['member_ids' => [301, 302], 'tags' => ['web', 'backend']],
42    'available_items' => ['orange', 'grape', 'kiwi'],
43    'global_config' => ['language' => 'en', 'timezone' => 'UTC']
44];
45
46// 各多次元配列を一次元配列に平坦化します。
47// array_intersect は多次元配列を直接比較すると期待通りの結果にならないため、このステップが重要です。
48$flatArray1 = flattenMultidimensionalArray($multiArray1);
49$flatArray2 = flattenMultidimensionalArray($multiArray2);
50$flatArray3 = flattenMultidimensionalArray($multiArray3);
51
52// 平坦化された配列間で共通の値を array_intersect を使用して検出します。
53// array_intersect は配列のキーを無視し、値のみを比較します。
54$commonValues = array_intersect($flatArray1, $flatArray2, $flatArray3);
55
56// 結果を出力して確認します。
57echo "--- 元の多次元配列 ---\n";
58echo "配列1:\n";
59print_r($multiArray1);
60echo "配列2:\n";
61print_r($multiArray2);
62echo "配列3:\n";
63print_r($multiArray3);
64
65echo "\n--- 平坦化された配列 ---\n";
66echo "平坦化された配列1:\n";
67print_r($flatArray1);
68echo "平坦化された配列2:\n";
69print_r($flatArray2);
70echo "平坦化された配列3:\n";
71print_r($flatArray3);
72
73echo "\n--- すべての多次元配列に共通する値 (array_intersect 適用後) ---\n";
74print_r($commonValues);
75
76/*
77期待される出力例:
78共通の値は 'php', 'web', 'apple', 'banana', 'orange', 'en' などが
79各配列に存在するかどうかに応じて検出されます。
80この例では 'php', 'web', 'banana', 'en' などが共通として検出されるはずです。
81*/

PHP 8のarray_intersect関数は、複数の配列に共通して存在する「値」を見つけ出すための関数です。引数には比較したい配列を複数指定し、戻り値として、すべての入力配列に共通する値だけを含む新しい配列を返します。この関数は配列のキーを無視し、値のみを比較するのが特徴です。

提供されたサンプルコードでは、多次元配列の中から共通の値を効率的に見つける方法を示しています。array_intersect関数は一次元配列の値を比較することを前提としているため、多次元配列を直接渡しても期待通りの結果は得られません。そこで、まずflattenMultidimensionalArrayというヘルパー関数を使用して、入力された多次元配列を再帰的に処理し、すべての要素を一次元配列に「平坦化」します。

具体的には、サンプルデータとして定義された複数の多次元配列$multiArray1$multiArray2$multiArray3がそれぞれflattenMultidimensionalArray関数によって一次元配列に変換されます。その後、これらの平坦化された配列$flatArray1$flatArray2$flatArray3array_intersect関数に渡すことで、すべての元の多次元配列内に共通して存在する値が正確に抽出され、$commonValuesとして得られます。この手順により、多次元構造を持つデータからでも、共通の値を見つけ出す処理を安全に実行できるのです。

PHPのarray_intersect関数は、複数の配列間で共通する「値」を検出します。この関数は一次元配列の値を比較対象とし、配列のキーは無視されます。そのため、多次元配列を直接array_intersectに渡しても、内部の要素まで深く比較することはなく、期待通りの結果は得られません。多次元配列内の共通の値を効率的に見つけるには、サンプルコードのように、事前に配列全体を再帰的に一次元配列へ「平坦化」する処理が不可欠です。これにより、array_intersectが正しく機能し、キーを無視して純粋な値の共通性を効果的に見つけ出すことができます。

PHP array_intersect の逆を実装する

1<?php
2
3/**
4 * 複数の配列の共通部分ではない要素を計算します。
5 * これは、全ての入力配列の和集合から、全ての入力配列の共通部分を除外した結果を返します。
6 * PHPのarray_intersect関数の「逆」として、いずれかの配列には存在するが、すべての配列には共通しない要素を抽出します。
7 *
8 * 例:
9 * $array1 = [1, 2, 3, 4];
10 * $array2 = [3, 4, 5, 6];
11 * $array3 = [4, 6, 7, 8];
12 *
13 * array_intersect($array1, $array2, $array3) は [4] を返します。
14 * array_intersect_opposite($array1, $array2, $array3) は [1, 2, 3, 5, 6, 7, 8] を返します。
15 *
16 * @param array $array 比較する最初の配列
17 * @param array ...$arrays 比較する残りの配列群 (可変引数)
18 * @return array 共通部分ではない要素の配列
19 */
20function array_intersect_opposite(array $array, array ...$arrays): array
21{
22    // 全ての入力配列を一つの配列にまとめる
23    $all_input_arrays = array_merge([$array], $arrays);
24
25    // 全ての配列に存在するユニークな要素の集合(和集合)を取得
26    // array_merge(...$all_input_arrays) は、PHP 7.4 以降で配列の展開に使用可能
27    $union_elements = array_unique(array_merge(...$all_input_arrays));
28
29    // 全ての配列に共通する要素の集合(共通部分)を取得
30    $common_elements = array_intersect($array, ...$arrays);
31
32    // 和集合から共通部分を除外した要素を返す(対称差の拡張)
33    return array_diff($union_elements, $common_elements);
34}
35
36// --- サンプルコード ---
37
38// 数値配列の例
39$array1 = [1, 2, 3, 4];
40$array2 = [3, 4, 5, 6];
41$array3 = [4, 6, 7, 8];
42
43echo "--- 数値配列の例 ---\n";
44echo "配列1: " . implode(', ', $array1) . "\n";
45echo "配列2: " . implode(', ', $array2) . "\n";
46echo "配列3: " . implode(', ', $array3) . "\n";
47
48// array_intersect の結果 (共通要素)
49$intersect_result = array_intersect($array1, $array2, $array3);
50echo "array_intersect の結果 (共通要素): ";
51print_r($intersect_result);
52// 期待される出力: Array ( [0] => 4 )
53
54// array_intersect_opposite の結果 (共通ではない要素)
55$opposite_result = array_intersect_opposite($array1, $array2, $array3);
56echo "array_intersect_opposite の結果 (共通ではない要素): ";
57print_r($opposite_result);
58// 期待される出力: Array ( [0] => 1 [1] => 2 [2] => 3 [4] => 5 [5] => 6 [6] => 7 [7] => 8 )
59
60// 文字列配列の例
61$fruits1 = ['apple', 'banana', 'orange', 'grape'];
62$fruits2 = ['banana', 'kiwi', 'orange', 'mango'];
63$fruits3 = ['orange', 'grape', 'lemon', 'banana'];
64
65echo "\n--- 文字列配列の例 ---\n";
66echo "配列1: " . implode(', ', $fruits1) . "\n";
67echo "配列2: " . implode(', ', $fruits2) . "\n";
68echo "配列3: " . implode(', ', $fruits3) . "\n";
69
70// array_intersect の結果 (共通要素)
71$intersect_fruits = array_intersect($fruits1, $fruits2, $fruits3);
72echo "array_intersect の結果 (共通要素): ";
73print_r($intersect_fruits);
74// 期待される出力: Array ( [1] => banana [2] => orange )
75
76// array_intersect_opposite の結果 (共通ではない要素)
77$opposite_fruits = array_intersect_opposite($fruits1, $fruits2, $fruits3);
78echo "array_intersect_opposite の結果 (共通ではない要素): ";
79print_r($opposite_fruits);
80// 期待される出力: Array ( [0] => apple [3] => grape [4] => kiwi [5] => mango [6] => lemon )
81
82?>

array_intersect_opposite関数は、複数の配列が与えられた際に、それら全ての配列に共通して存在する要素ではない要素を計算し、新しい配列として返すカスタム関数です。これは、PHPに標準で備わるarray_intersect関数が「全ての配列に共通する要素」を抽出するのに対し、その「逆」の要素群、つまり「いずれかの配列には存在するが、全ての配列には共通しない要素」を抽出する目的で作成されています。

この関数は、まず比較対象となる最初の配列を$arrayとして受け取ります。その後、比較したい残りの配列を...$arraysとして可変引数でいくつでも受け入れることができます。そして、共通部分ではない要素のみを含む新しい配列を戻り値として返します。

内部的な動作としては、まず全ての入力配列を一つにまとめて重複を取り除いた「和集合」を作成します。次に、array_intersect関数を使用して全ての配列に「共通する要素」の集合を計算します。最終的に、この「和集合」から「共通する要素」の集合を除外することで、目的とする「共通部分ではない要素」の配列を得ています。

例えば、[1, 2, 3, 4][3, 4, 5, 6][4, 6, 7, 8]という3つの数値配列に対しては、array_intersectが共通要素である[4]を返すのに対し、array_intersect_oppositeは共通ではない要素である[1, 2, 3, 5, 6, 7, 8]を返します。また、['apple', 'banana', 'orange', 'grape']['banana', 'kiwi', 'orange', 'mango']['orange', 'grape', 'lemon', 'banana']という文字列配列の場合、array_intersect['banana', 'orange']を、array_intersect_opposite['apple', 'grape', 'kiwi', 'mango', 'lemon']を返します。この関数は、複数のデータセットの中から、それぞれのデータセットに固有の要素や、全てのデータセットには共通しない要素を特定したい場合に非常に役立ちます。

このarray_intersect_opposite関数は、PHPのarray_intersectとは異なり、複数の配列の中から全ての配列に共通しない要素を抽出する自作関数です。PHPに組み込まれている関数ではないため、ご自身のコード内で定義して利用する必要があります。特に、array_merge(...$all_input_arrays)のような配列展開の記法はPHP 7.4以降で有効ですので、ご利用のPHPバージョンにご注意ください。本関数は配列のを比較します。戻り値の配列では、元の配列のキーが引き継がれる場合がありますので、もし連番のインデックスが必要な場合は、結果にarray_values()を適用すると良いでしょう。

関連コンテンツ

関連プログラミング言語