4

PHP で次の 2 つの配列を使用します。

$array1 = [
    2 => 'Search',
    1 => 'Front-End / GUI'
];
$array2 = [
    1 => 'Front-End / GUI',
    2 => 'Search'
];

配列比較関数のほとんどは順序を気にしません。を実行するarray_diffと、空の配列になります。

順序に関して2つの配列を比較する最も効率的/最短/クリーンな方法は何ですか?

  1. 等しいかどうか (真/偽) を示しますか?
  2. 違いを示しますか (PHPUnit など)?

PHPUnit で実行$this->assertEquals( $array1, $array2 );すると、理想的には次のような結果が得られるはずです。

Failed asserting that two arrays are equal.
--- Expected
+++ Actual
@@ @@
 Array (
-    2 => 'Search'
-    1 => 'Front-End / GUI'
+    1 => 'Front-End / GUI'
+    2 => 'Search'
 )

更新 - 解決策

これは、すべての要素が同じで、順序が異なる場合にのみ、一種の差分を生成します。PHP単体テスト:

public function test...() {
    $actual = someCall();
    $expected = [...];

    // tests for same elements
    $this->assertEquals( $expected, $actual );

    // tests for same order
    $diff = $this->array_diff_order( $expected, $actual );
    $this->assertTrue( $expected === $actual, "Failed asserting that two arrays are equal order.\n--- Expected\n+++ Actual\n@@ @@\n Array(\n$diff )" );
}

private function array_diff_order( $array1, $array2 ) {
    $out = '';
    while ((list($key1, $val1) = each($array1)) && (list($key2, $val2) = each($array2)) ) {
        if($key1 != $key2 || $val1 != $val2) $out .= "-    $key1 => '$val1' \n+    $key2 => '$val2'\n";
    }
    return $out;
}
4

3 に答える 3

7

===演算子を使用するだけです

$array = array(1 => "test", 2=> "testing");
$array2 = array(1 => "test", 2=> "testing");

var_dump($array === $array2);

$array2 = array(2 => "test", 1=> "testing");
var_dump($array === $array2);

戻り値

boolean true
boolean false

次に、 array_diff_assoc() を使用して違いを見つけます

while ((list($key1, $val1) = each($array)) && (list($key2, $val2) = each($array2)) ) {
    if($key1 != $key2 || $val1 != $val2) echo "- $key1 - $val1 \n + $key2 - $val2";
}

注文のためにいくつかの出力を与える必要があります

あなたの配列を使用すると、これが私に与えます

  • 2 - 検索 + 1 - フロントエンド / GUI
  • 1 - フロントエンド / GUI + 2 - 検索

必要に応じて出力を変更できます

于 2013-06-27T21:46:16.937 に答える
0

出力のような差分を生成するソリューションを探しているなら、これはイテレータが輝く場所だと思います:

配列ごとに 2 つのイテレータを用意し、それらを 1 つのループで同時にステップ実行して、キーと値のペアを比較するだけで、必要なほとんどすべてを実行できます。

$array1 = [
    2 => 'Search',
    1 => 'Front-End / GUI'
];
$array2 = [
    1 => 'Front-End / GUI',
    2 => 'Search'
];

$it0 = new ArrayIterator($array1);
$it1 = new ArrayIterator($array2);

while ($it0->valid() || $it1->valid()) {
    if ($it0->valid() && $it1->valid()) {
        if ($it0->key() != $it1->key() || $it0->current() != $it1->current()) {
            print "- ".$it0->key().' => '.$it0->current()."\n";
            print "+ ".$it1->key().' => '.$it1->current()."\n";
        }
        $it0->next();
        $it1->next();
    } elseif ($it0->valid()) {
        print "- ".$it0->key().' => '.$it0->current()."\n";
        $it0->next();
    } elseif ($it1->valid()) {
        print "+ ".$it1->key().' => '.$it1->current()."\n";
        $it1->next();
    }
}

次のような出力が得られます:

- 2 => Search
+ 1 => Front-End / GUI
- 1 => Front-End / GUI
+ 2 => Search

もちろん、このアイデアは、ネストされた配列を処理するように拡張する必要がRecursiveArrayIteratorあり、おそらく出力もより適切にフォーマットする必要があります。

于 2013-06-27T21:51:53.577 に答える