【问题标题】:How to get the difference between two multidimensional arrays of associative arrays in PHP? [duplicate]如何获取PHP中关联数组的两个多维数组之间的差异?
【发布时间】:2021-07-31 16:19:32
【问题描述】:

我的问题是我有两个不一定相同大小的数组,它们包含始终具有相同大小的关联数组,例如:

$a = array([0] => array(["ref"]=> string(19) "ygz121byr46dl4795eu", ["place"]=> string(5) "Paris", ["date"]=> string(25) "2012-03-14T16:42:47+01:00", ...), 
           [1] => array(["ref"]=> string(19) "cer123bur45dl4795ef", ["place"]=> string(8) "New-York", ["date"]=> string(25) "2015-06-14T05:05:49+01:00", ...),
           [2] => array(["ref"]=> string(19) "abc123abc12ab1234ab", ["place"]=> string(6) "London", ["date"]=> string(25) "2020-02-12T08:03:39+01:00", ...), 
     ...);

$b = array([0] => array(["ref"]=> string(19) "ygz121byr46dl4795eu", ["place"]=> string(5) "Paris", ["date"]=> string(25) "2012-03-14T16:42:47+01:00", ...), 
           [1] => array(["ref"]=> string(19) "cer123bur45dl4795ef", ["place"]=> string(8) "New-York", ["date"]=> string(25) "2015-06-14T05:05:49+01:00", ...), 
     ...);

我尝试了几种方法,但似乎没有任何效果,或者我只得到没有值的键。 我想在一个数组中得到差异($a 中的所有元素都不存在 $b),所以这里的结果是:

$result = array( array(["ref"]=> string(19) "abc123abc12ab1234ab", ["place"]=> string(6) "London", ["date"]=> string(25) "2020-02-12T08:03:39+01:00", ...), 
          ...);

“ref”键是每个数组的唯一字段,所以我需要在 $result 中所有“ref”键不在 $b 中的文档

编辑:我找到了 (https://stackoverflow.com/a/42530586/15742179) 一种使用 array_diff()、array_map()、json_encode() 和 decode() 方法的方法。感谢 Ifnot

// compare all value
$result = array_diff(array_map('json_encode', $a), array_map('json_encode', $b));

// decode the result
$result = array_map('json_decode', $result);

【问题讨论】:

  • 先定义“差异”。 $a 中的所有元素都不存在 $b?另一种方式?两个都?相同的元素,但在不同的键上也会构成差异吗?
  • 比较时顺序重要吗?
  • 感谢 El-Vanja,为了更清楚,我已经编辑了问题
  • 数据在$a和$b之间不一定按相同的顺序排序,所以我认为这里的顺序并不重要但我可能错了。

标签: php arrays multidimensional-array associative-array


【解决方案1】:

您需要遍历要过滤的元素集或过滤器集。这是一种可能的方法:

<?php
$a = [
  ["ref" => "bee898d8739aa8b2212", "place" => "Berlin"],
  ["ref" => "ygz121byr46dl4795eu", "place" => "Paris"],
  ["ref" => "cer123bur45dl4795ef", "place" => "New-York"],
  ["ref" => "abc123abc12ab1234ab", "place" => "London"]
];

$b = [
  ["ref" => "ygz121byr46dl4795eu", "place" => "Paris"],
  ["ref" => "cer123bur45dl4795ef", "place" => "New-York"],
];

$filter = array_column($b, "ref");
$result = array_combine(array_column($a, "ref"), $a);

array_walk($filter, function($entry) use (&$result) {
  unset($result[$entry]);
});

print_r(array_values($result));

另一种方法是使用 php 的 array_filter() 函数:

<?php
$a = [
  ["ref" => "bee898d8739aa8b2212", "place" => "Berlin"],
  ["ref" => "ygz121byr46dl4795eu", "place" => "Paris"],
  ["ref" => "cer123bur45dl4795ef", "place" => "New-York"],
  ["ref" => "abc123abc12ab1234ab", "place" => "London"]
];

$b = [
  ["ref" => "ygz121byr46dl4795eu", "place" => "Paris"],
  ["ref" => "cer123bur45dl4795ef", "place" => "New-York"],
];

array_walk($b, function($filter) use (&$a) {
  $a = array_filter($a, function($entry) use ($filter) {
    return $entry["ref"] != $filter["ref"];
  });
});

print_r($a);

输出显然是:

Array
(
    [0] => Array
        (
            [ref] => bee898d8739aa8b2212
            [place] => Berlin
        )
    [1] => Array
        (
            [ref] => abc123abc12ab1234ab
            [place] => London
        )
)

【讨论】:

    【解决方案2】:

    通过将它们合并在一起来制作一个数组$c, 使用函数 array_columnarray_unique 获取唯一性 ref 并通过array_diff_assoc 获取重复项,然后使用array_diff 轻松获取差异引用,然后遍历数组并仅在$diff 数组中获取它们的引用。

    $c = [...$a, ...$b];
    
    $arr = array_column($c, "ref");
    $unique = array_unique($arr);
    $duplicates = array_diff_assoc($arr, $unique);
    
    $diff = array_diff($unique, $duplicates);
    $output = [];
    foreach ($c as $d) {
        foreach ($d as $key => $value) {
            if(in_array($d[$key], $diff))
                $output[] = $d;
        }
    }
    echo "<pre>",print_r($output),"</pre>";
    

    输出

    Array
    (
        [0] => Array
            (
                [ref] => bee898d8739aa8b2212
                [place] => Berlin
            )
    
        [1] => Array
            (
                [ref] => abc123abc12ab1234ab
                [place] => London
            )
    
    )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-05-01
      • 1970-01-01
      • 2020-10-08
      • 2017-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多