【PHP8.x】array_udiff関数の使い方
array_udiff関数は、複数の配列を比較し、最初の配列にのみ存在する要素を、ユーザー定義の比較関数を用いて検出する関数です。この関数は、与えられた複数の配列の中から、最初の配列(第一引数)に存在する値のうち、他のどの配列にも含まれていない値だけを抽出して新しい配列として返します。
特に、値の比較方法をプログラマが自由に定義できる点が特徴です。通常は厳密な等価性(===)で要素が比較されますが、この関数では、比較したい値の特性(例えばオブジェクトの特定のプロパティや、文字列の大文字・小文字を区別しない比較など)に基づいて、ユーザーが独自のコールバック関数を指定できます。このコールバック関数は、二つの要素を受け取り、最初の要素が二番目の要素より小さい場合は負の値を、等しい場合はゼロを、大きい場合は正の値を返す必要があります。
第一引数には比較の基準となる配列を、第二引数以降には比較対象となる他の配列を複数指定できます。最後の引数には、値の比較に使用するコールバック関数を渡します。戻り値は、最初の配列にのみ存在する要素で構成される新しい配列となりますが、元の配列のキーは保持されます。この機能は、複雑な比較ロジックが必要な場合に非常に役立ちます。
基本的な使い方
構文(syntax)
<?php
function userDefinedComparisonFunction($valueA, $valueB) {
if ($valueA === $valueB) {
return 0;
}
return ($valueA > $valueB) ? 1 : -1;
}
$arrayBase = ["apple", "banana", "orange", "grape"];
$arrayCompare1 = ["banana", "kiwi"];
$arrayCompare2 = ["apple", "lemon"];
$result = array_udiff($arrayBase, $arrayCompare1, $arrayCompare2, 'userDefinedComparisonFunction');
?>
引数(parameters)
array $array, array ...$arrays, callable $value_compare_func
- array $array: 比較対象となる最初の配列
- array ...$arrays: 比較対象となる残りの配列
- callable $value_compare_func: 配列要素の比較に使用するコールバック関数
戻り値(return)
array
2つ以上の配列を、ユーザー定義の比較関数を用いて比較し、差分のある要素のみを要素として含む新しい配列を返します。
サンプルコード
PHP array_udiff_assocでキーと値の差を比較する
<?php
/**
* array_udiff_assoc の使用例
*
* この関数は、ユーザー定義の比較関数を使用して配列の値の差を計算し、
* さらにキーも比較して差を特定します。
* 最初の配列 ($array1) に存在する要素のうち、
* 比較対象の他の配列 ($array2, $array3...) のいずれかの要素と
* 「キーが同一」であり、かつ「値がコールバック関数で等しい」と判断されたものを除外します。
* それ以外の要素が結果として返されます。
*
* 主にオブジェクトの比較など、標準の比較演算子では意図した結果が得られない場合に有用です。
*/
function demonstrateArrayUdiffAssoc(): void
{
// 比較に使用するコールバック関数を定義します。
// この例では、文字列の長さを比較します。
// 戻り値: -1 ($aが$bより小さい), 0 ($aと$bが等しい), 1 ($aが$bより大きい)
$valueCompareFunc = function (string $a, string $b): int {
$lenA = strlen($a);
$lenB = strlen($b);
if ($lenA === $lenB) {
return 0; // 長さが同じなら等しいと判断
}
return ($lenA < $lenB) ? -1 : 1;
};
// 比較する配列を定義します。キーと値の両方に注目してください。
$array1 = [
"a" => "apple", // 長さ 5
"b" => "banana", // 長さ 6
"c" => "cherry", // 長さ 6
"d" => "date", // 長さ 4
];
$array2 = [
"e" => "apricot", // 長さ 7
"f" => "berry", // 長さ 5 (appleと同じ長さ)
"c" => "grape", // 長さ 5 (cherryとは異なる長さ)
];
$array3 = [
"g" => "fig", // 長さ 3
"d" => "pear", // 長さ 4 (dateと同じ長さ、キーも同じ)
];
echo "--- array_udiff_assoc のデモンストレーション ---" . PHP_EOL;
echo "配列1: " . json_encode($array1) . PHP_EOL;
echo "配列2: " . json_encode($array2) . PHP_EOL;
echo "配列3: " . json_encode($array3) . PHP_EOL;
echo PHP_EOL;
// array_udiff_assoc を使用して、array1 と array2, array3 の差を計算します。
// 結果には、array1 の要素のうち、以下の条件のいずれかを満たすものが含まれます:
// 1. array2, array3 のいずれの配列にも同じキーの要素が存在しない。
// 2. 同じキーの要素が存在するが、その値が $valueCompareFunc で比較して等しくないと判断された。
$result = array_udiff_assoc($array1, $array2, $array3, $valueCompareFunc);
echo "結果 (array_udiff_assoc(\$array1, \$array2, \$array3, \$valueCompareFunc)):" . PHP_EOL;
echo json_encode($result, JSON_PRETTY_PRINT) . PHP_EOL;
/*
* 結果の解説:
* - "a" => "apple": array2, array3 にキー "a" がないため結果に含まれます。
* - "b" => "banana": array2, array3 にキー "b" がないため結果に含まれます。
* - "c" => "cherry": array2 にキー "c" ("grape") が存在します。
* キーは一致しますが、値 "cherry" (長さ6) と "grape" (長さ5) は
* $valueCompareFunc で等しくないと判断されるため結果に含まれます。
* - "d" => "date": array3 にキー "d" ("pear") が存在します。
* キーは一致し、値 "date" (長さ4) と "pear" (長さ4) は
* $valueCompareFunc で等しいと判断されるため結果から除外されます。
*
* 最終的な結果: ["a" => "apple", "b" => "banana", "c" => "cherry"]
*/
}
// 関数の実行
demonstrateArrayUdiffAssoc();
PHP 8のarray_udiff_assoc
関数は、複数の配列の差分を、ユーザーが定義した比較関数と配列のキーを考慮して検出するものです。この関数は、最初の配列に含まれる要素のうち、比較対象となる他の配列のいずれかにも、同じキーと、ユーザー定義の比較関数で「等しい」と判断される値を持つ要素が存在する場合、それらの要素を結果から除外します。最終的に、最初の配列から除外されなかった要素のみが、キーを保持したまま新しい配列として返されます。
主な引数は以下の通りです。$array
には比較の基準となる最初の配列を指定し、...$arrays
には比較対象となる2番目以降の配列を複数指定できます。$value_compare_func
には配列の「値」を比較するためのコールバック関数を指定します。この比較関数は2つの引数を受け取り、最初の引数が2番目の引数より小さい場合は負の整数、等しい場合はゼロ、大きい場合は正の整数を返す必要があります。
この関数は、通常の比較演算子では意図する比較ができないオブジェクトやカスタムデータ型を含む配列の差分を、キーと値の両面から検出したい場合に特に有用です。戻り値は、差分が含まれる配列となります。
array_udiff_assoc
関数は、キーと値の両方を比較して配列の差分を求めます。値の比較には、引数で指定するコールバック関数が使われます。このコールバック関数は必ず整数を返すように実装し、戻り値が0のときに値が「等しい」と判断される点に注意が必要です。0以外の正または負の整数は「等しくない」と扱われます。比較の基準は最初の引数に指定した配列となり、引数の順序で結果が変わります。キーが同じでも、コールバック関数で値が等しくないと判断されれば、その要素は差分として結果に含まれます。大規模なデータでは処理速度に影響する場合があるため、性能が重要な場面では注意して使用してください。