简体   繁体   English

按顺序比较PHP中数组的最有效方法?

[英]Most efficient way to compare arrays in PHP by order?

Take these two arrays in PHP: 在PHP中采用以下两个数组:

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

Most of the array comparison functions do not care about order. 大多数数组比较函数不关心顺序。 Doing an array_diff will result in an empty array. 进行array_diff将导致一个空数组。

What's the most efficient / shortest / cleanest way to compare two arrays with regard to order and: 比较两个数组的顺序和最有效/最短/最干净的方法是什么:

  1. show whether or not they are equal (true / false)? 显示它们是否相等(对/错)?
  2. show the difference (such as for PHPUnit)? 显示差异(例如对于PHPUnit)?

Running $this->assertEquals( $array1, $array2 ); 运行$this->assertEquals( $array1, $array2 ); in PHPUnit ideally should yield something like: 在PHPUnit中,理想情况下应产生如下内容:

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

Update - Solution 更新-解决方案

This generates a sort-of diff only if all elements are same, just in different order. 仅当所有元素都相同(只是顺序不同)时,才生成排序差异。 PHPUnit Tests: PHPUnit测试:

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;
}

You can just use the === operator 您可以只使用===运算符

$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);

returns 退货

boolean true
boolean false

then use array_diff_assoc() to find the differences 然后使用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";
}

Should give some output for order 应该给订单一些输出

Using your array this gives me 使用您的数组,这给了我

  • 2 - Search + 1 - Front-End / GUI 2-搜索+ 1-前端/ GUI
  • 1 - Front-End / GUI + 2 - Search 1-前端/ GUI + 2-搜索

you can change the output to how ever you need it 您可以将输出更改为所需的输出

If you are looking for a solution to generate a diff like output, i think this is a place where iterator shine: 如果您正在寻找生成差异输出的解决方案,我认为这是迭代器大放异彩的地方:

Just having two iterators for each array and stepping trough on them simultaneously in one loop and compare key + value pairs can do almost everything you need: 每个数组只有两个迭代器,并在一个循环中同时步进通过它们,并比较键+值对几乎可以满足您的所有需求:

$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();
    }
}

Will output something like: 将输出类似:

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

This idea of course should be expanded to handle nested arrays with RecursiveArrayIterator and probably format the output better too. 当然,应该将此想法扩展为使用RecursiveArrayIterator处理嵌套数组,并且可能还可以更好地格式化输出。

You want array_diff_assoc() , which compares values AND keys. 您需要array_diff_assoc() ,它比较值和键。 array_diff() considers only values. array_diff()仅考虑值。


followup: Works fine here: 跟进:在这里工作正常:

php > $arr1 = array(2 => 'Search', 1 => 'Front');
php > $arr2 = array(1 => 'Search', 2 => 'Front');
php > var_dump(array_diff_assoc($arr1, $arr2));
array(2) {
  [2]=>
  string(6) "Search"
  [1]=>
  string(5) "Front"
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM