PHP比较两个数组并仅返回唯一的数组值

时间:2014-09-23 01:53:29

标签: php arrays multidimensional-array

完成一个开源域名注册商插件,并在确定何时进行更改时遇到一些麻烦。

$saved = array(
        array( 'domain' => 'mydomain.com', 'record' => 'A', 'value' => '8.8.8.8' ),
        array( 'domain' => 'mydomain.com', 'record' => 'NS', 'value' => 'ns1.mydomain.com' )
    );

$new = array(
        array( 'domain' => 'mydomain.com', 'record' => 'A', 'value' => '4.4.4.4' ),
        array( 'domain' => 'mydomain.com', 'record' => 'NS', 'value' => 'ns1.mydomain.com' ),
        array( 'domain' => 'sub.mydomain.com', 'record' => 'A', 'value' => '1.2.3.4' ),
    );

$saved是已在域名注册商处保存的值,仅用于比较。

$new是从处理网站表单的应用程序返回的数组。

我需要以某种方式仅返回具有已更新的值或尚未存在/匹配$saved的值的数组。

基本上我正在寻找的返回数组是:

array(
    array( 'domain' => 'mydomain.com', 'record' => 'A', 'value' => '4.4.4.4' )
    array( 'domain' => 'sub.mydomain.com', 'record' => 'A', 'value' => '1.2.3.4' ),
);

因为$saved value 8.8.8.8已从4.4.4.4更新为sub.mydomain.com$savedarray_intersect中的任何数组都不匹配这是一个新的条目。

使用array_uintersect我能够让它返回更新了值的数组,但不幸的是它仍然包含匹配的数组。如果我能以某种方式删除那些正是我需要的东西。

这是一个演示: http://glot.io/php/529b0c6d2fd16fe221f86bb521155384

也许使用带有回调的{{1}}检查数组是否匹配并取消设置?寻找一些帮助,因为我现在坚持这一点。

谢谢!

2 个答案:

答案 0 :(得分:1)

嗯,在这种情况下,你可以通过序列化将它们展平,然后将它们映射,最后array_dif()

$result = array_map('unserialize', array_diff(array_map('serialize', $new), array_map('serialize', $saved)));

应根据例子生成:

Array
(
    [0] => Array
        (
            [domain] => mydomain.com
            [record] => A
            [value] => 4.4.4.4
        )

    [2] => Array
        (
            [domain] => sub.mydomain.com
            [record] => A
            [value] => 1.2.3.4
        )

)

答案 1 :(得分:1)

array_udiff应该在这里工作。

以下比较函数中的某些内容作为自定义回调应该可以解决问题:

$saved = array(
        array( 'domain' => 'mydomain.com', 'record' => 'A', 'value' => '8.8.8.8' ),
        array( 'domain' => 'mydomain.com', 'record' => 'NS', 'value' => 'ns1.mydomain.com' )
    );

$new = array(
        array( 'domain' => 'mydomain.com', 'record' => 'A', 'value' => '4.4.4.4' ),
        array( 'domain' => 'mydomain.com', 'record' => 'NS', 'value' => 'ns1.mydomain.com' ),
        array( 'domain' => 'sub.mydomain.com', 'record' => 'A', 'value' => '1.2.3.4' ),
    );


function cmpr($a, $b) {
    foreach($a as $k=>$v) {
        if ($b[$k] !== $v)
            return -1;
    }
    return 0;
}

var_dump(array_udiff($new, $saved, 'cmpr'));

输出应该与预期的一样:

array(2) {
  [0]=>
  array(3) {
    ["domain"]=>
    string(12) "mydomain.com"
    ["record"]=>
    string(1) "A"
    ["value"]=>
    string(7) "4.4.4.4"
  }
  [2]=>
  array(3) {
    ["domain"]=>
    string(16) "sub.mydomain.com"
    ["record"]=>
    string(1) "A"
    ["value"]=>
    string(7) "1.2.3.4"
  }
}