使用array_diff_assoc()或获取多维数组的差异

时间:2014-03-12 14:33:36

标签: php arrays multidimensional-array

我一直在努力解决我认为现在应该是一个非常简单的问题,而且无法解决问题。

我有两个数组,这些数组包含有关id,linklabel和url的信息,格式如下:

$pageids
--------
Array ( 
[0] => Array 
( [id] => 1 
  [linklabel] => Home 
  [url] => home )

[1] => Array 
( [id] => 2 
  [linklabel] => Graphic Design 
  [url] => graphicdesign ) 

[2] => Array 
( [id] => 3 
  [linklabel] => Other Design 
  [url] => otherdesign ) 

[3] => Array 
( [id] => 6 
  [linklabel] => Logo Design 
  [url] => logodesign ) 

[4] => Array 
( [id] => 15 
  [linklabel] => Content Writing 
  [url] => contentwriting ) 
) 


$parentpage
-----------
Array ( 
[0] => Array 
( [id] => 2 
  [linklabel] => Graphic Design 
  [url] => graphicdesign ) 

[1] => Array 
( [id] => 3 
  [linklabel] => Other Design 
  [url] => otherdesign ) ) 

我现在正在尝试比较这两个,以便找到$pageids但不在$parentpage中的信息 - 这将构成另一个名为$pageWithNoChildren的数组。但是当我使用以下代码时:

$pageWithNoChildren = array_diff_assoc($pageids,$parentpage);

array_diff_assoc()在数组的第一级运行,因此看到$pageids$parentpages都有[0]和[1]键,因此忽略它们并返回所有来自[2]的$pageids的信息。但是,我希望它能够查看嵌套数组的内容,并比较这些内容。我需要它来查看哪个id,linklabel和url位于$pageids而不是$parentpages并返回这些值。

如何让array_diff_assoc()在嵌套数组的键上运行而不是第一个数组的键,因此最终结果是包含[0],[3]内容的数组和[4]来自$pageids的数组?

4 个答案:

答案 0 :(得分:15)

要检查多次尝试,请尝试以下方法:

$pageWithNoChildren = array_map('unserialize',
    array_diff(array_map('serialize', $pageids), array_map('serialize', $parentpage)));
  • array_map()通过serialize()
  • 运行主阵列的每个子阵列
  • serialize()将每个子数组转换为该子数组的字符串表示形式
  • 主数组现在的值不是数组,而是子数组的字符串表示
  • array_diff()现在每个要比较的数组都有一维数组
  • 返回差异后array_map()运行数组结果(差异)到unserialize()以将字符串表示形式转换回子数组

Q.E.D。

答案 1 :(得分:2)

正确的方法https://github.com/yapro/helpers/blob/master/src/ArrayHelper.php

class ArrayHelper
{
    /**
     * @param array $array1
     * @param array $array2
     * @return array
     */
    function arrayDiffAssocMultidimensional(array $array1, array $array2): array
    {
        $difference = [];
        foreach ($array1 as $key => $value) {
            if (is_array($value)) {
                if (!array_key_exists($key, $array2)) {
                    $difference[$key] = $value;
                } elseif (!is_array($array2[$key])) {
                    $difference[$key] = $value;
                } else {
                    $multidimensionalDiff = $this->arrayDiffAssocMultidimensional($value, $array2[$key]);
                    if (count($multidimensionalDiff) > 0) {
                        $difference[$key] = $multidimensionalDiff;
                    }
                }
            } else {
                if (!array_key_exists($key, $array2) || $array2[$key] !== $value) {
                    $difference[$key] = $value;
                }
            }
        }
        return $difference;
    }
}

答案 2 :(得分:1)

来自@AbraCadaver的非常好的解决方案,但就像我在评论中所说的那样,可能存在关联数组的元素在任何地方都不相同的情况,因此自定义函数将按索引/键对它们进行排序首先是方便的:

function sortAndSerialize($arr){
    ksort($arr);
    return serialize($arr);
}

array_map('unserialize', array_diff(array_map('sortAndSerialize', $pageids), array_map('sortAndSerialize', $parentpage)));

答案 3 :(得分:1)

@AbraCadaver的回答非常好,@ qdev的评论很客气。我的建议只是一个很小的调整,以使@qdev中已经提出的答案更加可移植。将函数分配给变量使其可以在类方法等中使用。

embedded_distance = layers.Lambda(lambda x: K.sqrt(K.sum(K.square(x), axis=-1, keepdims=True)), name='euclidean_distance')(embedded_distance)