PHP
PHP小ネタ

2つ配列の要素集合が等しいか判定する

More than 1 year has passed since last update.

PHPには配列演算子というものがあり、2つの配列を比較することができます。

http://php.net/manual/ja/language.operators.array.php

しかしこの配列演算子(==)はキーの値も比較するので、集合として等しいかどうか判定したい場合には使えません。

==演算子
$a = array( 'apple', 'banana', 'cake' );
$b = array( 'cake', 'banana', 'apple' );

echo ($a == $b) ? 'TRUE' : 'FALSE' . PHP_EOL;
FALSE

switch文は==比較なので、やはりcase文でヒットしません(する人もいないと思いますが)。

array_xxx系の関数を調べましたが、そのような目的で使用できる関数はなさそうです。
(あったら教えて下さい!)

そこで、2つの集合が等しいかどうか、キー関係なく判定する関数を作ってみました。

2つの集合が等しいかどうか、キー関係なく判定する関数
<?php:array_equal_set
function array_equal_set( $a, $b )
{
    $diff_a_to_b = array_diff($a, $b);
    $diff_b_to_a = array_diff($b, $a);
    return empty($diff_a_to_b) && empty($diff_b_to_a);
}

$test_cases = array(
        /* 0 */ array( 'A', 'B', 'C' ),
        /* 1 */ array( 'A', 'C', 'B' ),
        /* 2 */ array( 'B', 'A', 'C' ),
        /* 3 */ array( 'B', 'C', 'A' ),
        /* 4 */ array( 'C', 'A', 'B' ),
        /* 5 */ array( 'C', 'B', 'A' ),
        /* 6 */ array( 'A', 'B', 'C', 'D' ),
        /* 7 */ array( 'A', 'B', 'D' ),
        /* 8 */ array( 'A', 'B', 'B' ),
        /* 9 */ array( 'A', 'B' ),
        /* 10 */ array( 'A', 'B', 'C', 'B' ),
    );

// test
$data = array( 'A', 'B', 'C' );
foreach( $test_cases as $key => $test ){
    $result = array_equal_set( $test, $data ) ? 'TRUE' : 'FALSE';
    echo "[$key]$result" . PHP_EOL;
}
[0]TRUE
[1]TRUE
[2]TRUE
[3]TRUE
[4]TRUE
[5]TRUE
[6]FALSE
[7]FALSE
[8]FALSE
[9]FALSE
[10]TRUE

 中身の処理は2つの集合の差分をarray_diffで取得し、それがA集合⇒B集合の差分、B集合⇒A集合の差分ともに空集合であることを確認しています。

 ですので、

( 'A', 'B', 'C', 'B' ) = ( 'A', 'B', 'C' )

 も真(TRUE)と判定されます。
 もちろん、2つの集合の値の順序はばらばらでも真(TRUE)と判定されます(テストケースでは[0]~[5])。

 具体的には、クライアントから送信されるフォームの値が、本当に必要なキーを含んでいるかチェックする場合などに使えると思います。