2024年PHP开发者大会日本站

array_diff_assoc

(PHP 4 >= 4.3.0, PHP 5, PHP 7, PHP 8)

array_diff_assoc计算数组的差集,并额外进行索引检查

描述

array_diff_assoc(数组 $array, 数组 ...$arrays): 数组

比较arrayarrays,并返回差集。与array_diff()不同的是,它也使用数组键进行比较。

参数

array

要从中进行比较的数组

arrays

要比较的数组

返回值

返回一个数组,其中包含array中所有不在其他任何数组中的值。

变更日志

版本 描述
8.0.0 此函数现在可以只用一个参数调用。以前,至少需要两个参数。

示例

示例 #1 array_diff_assoc() 示例

在这个例子中,"a" => "green" 对在两个数组中都存在,因此它不在函数的输出中。与之不同的是,0 => "red" 对在输出中,因为"red" 的键在第一个数组中自动赋值为 0,而在第二个数组中赋值为 1,因为键 0 已经被 yellow占用。

<?php
$array1
= array("a" => "green", "b" => "brown", "c" => "blue", "red");
$array2 = array("a" => "green", "yellow", "red");
$result = array_diff_assoc($array1, $array2);
print_r($result);
?>

以上示例将输出

Array
(
    [b] => brown
    [c] => blue
    [0] => red
)

示例 #2 array_diff_assoc() 示例

只有当(string) $elem1 === (string) $elem2 时,来自键=>值对的两个值才被认为是相等的。换句话说,会进行严格检查,因此字符串表示必须相同。

<?php
$array1
= array(0, 1, 2);
$array2 = array("00", "01", "2");
$result = array_diff_assoc($array1, $array2);
print_r($result);
?>

以上示例将输出

Array
(
    [0] => 0
    [1] => 1
)

注释

注意: 此函数仅检查 n 维数组的一个维度。例如,可以使用 array_diff_assoc($array1[0], $array2[0]); 检查更深的维度。

注意: 比较具有更多键的相似数组时,请确保参数按正确的顺序传递。新数组应位于列表的首位。

参见

添加注释

用户贡献的注释 21 条注释

Giosh
11 年前
来自 "chinello at gmail dot com"(以及其他人)的 array_diff_assoc_array 对于包含空值的数组将无法正常工作。这是因为当数组键不存在或设置为 null 时,!isset 为 true。

(抱歉,缩进样式已更改)
<?php
函数 array_diff_assoc_recursive($array1, $array2) {
$difference=array();
遍历(
$array1 作为 $key => $value) {
如果(
is_array($value) ) {
如果( !isset(
$array2[$key]) || !is_array($array2[$key]) ) {
$difference[$key] = $value;
} 否则 {
$new_diff = array_diff_assoc_recursive($value, $array2[$key]);
如果( !empty(
$new_diff) )
$difference[$key] = $new_diff;
}
} 否则如果( !
array_key_exists($key,$array2) || $array2[$key] !== $value ) {
$difference[$key] = $value;
}
}
返回
$difference;
}
?>

下面是一个例子(注意输出中的索引 'b')
<?php
$a1
=array( 'a' => 0, 'b' => null, 'c' => array( 'd' => null ) );
$a2=array( 'a' => 0, 'b' => null );

var_dump( array_diff_assoc_recursive( $a1, $a2 ) );
var_dump( chinello_array_diff_assoc_recursive( $a1, $a2 ) );
?>
array(1) {
["c"]=>
array(1) {
["d"]=>
NULL
}
}

array(2) {
["b"]=>
NULL
["c"]=>
array(1) {
["d"]=>
NULL
}
}
联系 pascalopitz at com
17 年前
参数的顺序确实会影响结果

<?php
$a
= array(
'x' => 'x',
'y' => 'y',
'z' => 'z',
't' => 't',
);

$b = array(
'x' => 'x',
'y' => 'y',
'z' => 'z',
't' => 't',
'g' => 'g',
);

print_r(array_diff_assoc($a, $b));
print_r(array_diff_assoc($b, $a));
?>

输出

数组
(
)
数组
(
[g] => g
)
telefoontoestel at hotmail dot com
10 年前
之前的递归 array_diff_assoc 帖子失败,因为 isset 在包含 null 值的数组元素上返回 false。我已经更新了代码,以便它也能比较 null 值。

<?php
函数 array_diff_assoc_recursive($array1, $array2)
{
遍历(
$array1 作为 $key => $value)
{
如果(
is_array($value))
{
如果(!isset(
$array2[$key]))
{
$difference[$key] = $value;
}
elseif(!
is_array($array2[$key]))
{
$difference[$key] = $value;
}
否则
{
$new_diff = array_diff_assoc_recursive($value, $array2[$key]);
如果(
$new_diff != FALSE)
{
$difference[$key] = $new_diff;
}
}
}
elseif(!
array_key_exists($key, $array2) || $array2[$key] != $value)
{
$difference[$key] = $value;
}
}
返回 !isset(
$difference) ? 0 : $difference;
}
?>
Michael Richey
11 年前
如果您正在寻找真正的 array_diff_assoc,比较数组以确定两者之间的差异,查找两者的缺失值,您可以将此与 array_merge 一起使用。

$a = array('a'=>1,'b'=>2,'c'=>3);
$b = array('a'=>1,'b'=>2,'d'=>4);
print_r(array_diff_assoc($a,$b));
// 返回
array
(
[c] => 3
)

print_r(array_diff_assoc($b,$a));
// 返回
array
(
[d] => 4
)

print_r(array_merge(array_diff_assoc($a,$b),array_diff_assoc($b,$a)));
// 返回
array
(
[c] => 3
[d] => 4
)
chinello at gmail dot com
17 年前
以下代码将递归地执行 array_diff_assoc,这将在多维级别上计算差异。如果键不存在,并且 error_reporting 设置为 E_ALL,则不会显示任何通知。

<?php
函数 array_diff_assoc_recursive($array1, $array2)
{
遍历(
$array1 作为 $key => $value)
{
如果(
is_array($value))
{
如果(!isset(
$array2[$key]))
{
$difference[$key] = $value;
}
elseif(!
is_array($array2[$key]))
{
$difference[$key] = $value;
}
否则
{
$new_diff = array_diff_assoc_recursive($value, $array2[$key]);
如果(
$new_diff != FALSE)
{
$difference[$key] = $new_diff;
}
}
}
elseif(!isset(
$array2[$key]) || $array2[$key] != $value)
{
$difference[$key] = $value;
}
}
返回 !isset(
$difference) ? 0 : $difference;
}
?>

[danbrown AT php DOT net 注:这是之前已删除笔记的成果组合。贡献者包括(Michael Johnson)、(jochem AT iamjochem DAWT com)、(sc1n AT yahoo DOT com) 和 (anders DOT carlsson AT mds DOT mdh DOT se)。]
dev5er6 at gmail dot com
10 年前
更像原始函数的工作方式

<?php

function array_diff_assoc_recursive ( )
{
$args = func_get_args ( );
$diff = array ( );
foreach (
array_shift ( $args ) as $key => $val )
{
for (
$i = 0, $j = 0, $tmp = array ( $val ) , $count = count ( $args ); $i < $count; $i++ )
if (
is_array ( $val ) )
if ( !isset (
$args[$i][$key] ) || !is_array ( $args[$i][$key] ) || empty( $args[$i][$key] ) )
$j++;
else
$tmp[] = $args[$i][$key];
elseif ( !
array_key_exists ( $key, $args[$i] ) || $args[$i][$key] !== $val )
$j++;
if (
is_array ( $val ) )
{
$tmp = call_user_func_array ( __FUNCTION__, $tmp );
if ( ! empty (
$tmp ) ) $diff[$key] = $tmp;
elseif (
$j == $count ) $diff[$key] = $val;
}
elseif (
$j == $count && $count ) $diff[$key] = $val;
}

return
$diff;
}

?>
[email protected]
7年前
如果值无法转换为字符串,array_diff_assoc 将会失败。
[email protected]
19年前
大家好:
对于PHP版本小于4.3……

<?php
/**
* 版本< 4.3 的 array_diff_assoc
**/
if (!function_exists('array_diff_assoc'))
{
function
array_diff_assoc($a1, $a2)
{
foreach(
$a1 as $key => $value)
{
if(isset(
$a2[$key]))
{
if((string)
$value !== (string) $a2[$key])
{
$r[$key] = $value;
}
}else
{
$r[$key] = $value;
}
}
return
$r ;
}
}

?>
Alexander Podgorny
18年前
注意:diff_array 还删除了与第二个数组中的值匹配的所有重复值。

<?php
$array1
= array("a","b","c","a","a");
$array2 = array("a");

$diff = array_diff($array1,$array2);

// 结果:array("b","c") 重复的"a"值被删除了
?>
[email protected]
21年前
如果您知道键但不知道值,则可以这样做来取消设置数组中的元素

<?php
$a
= array("foo", "bar", "baz", "quux");
$b = array(1, 3); // 要删除的元素

foreach($b as $e)
unset(
$a[$e]);
?>

当然,如果 $b 包含许多元素或动态生成,则此方法最有意义。
[email protected]
13年前
一种相当简单(但效率不高)的方法来比较值不是字符串的一级数组
array_map('unserialize',array_diff_assoc(array_map('serialize',$arr1),array_map('serialize',$arr2)))
可能对调试有用(这就是我使用它的目的)。
[email protected]
16年前
array_diff_assoc 也可用于查找数组中的重复项

<?php
$arr
= array('1','2','3','4','3','2','5');
$uniques = array_unique($arr);
// array_diff 在这里不起作用,array_diff_assoc 起作用,因为它考虑了键 //。
$dups = array_diff_assoc($arr, $uniques);

print_r($dups);
?>

注意:$dups 的索引不是像 C 程序员预期的那样严格按顺序排列。
[email protected]
17 年前
要比较 n 维数组,只需使用这个

<?php
function array_diff_values($tab1, $tab2)
{
$result = array();
foreach(
$tab1 as $values) if(! in_array($values, $tab2)) $result[] = $values;
return
$result;
}
?>
[email protected]
6年前
接受多个 n 级数组作为参数的递归实现

<?php
function recursiveDiff() {
$arrs = func_get_args();
$first = array_shift($arrs);
$diff = [];

foreach(
$first as $key => $value) {
$values = array_map(function($arr) use($key){
if (
is_array($arr) && !array_key_exists($key, $arr))
return
null;

return
$arr[$key];
},
$arrs);

if (
in_array($value, $values))
continue;

if (
is_array($value)) {
array_unshift($values, $value);
$diff[$key] = call_user_func_array(__FUNCTION__, $values);
continue;
}

$diff[$key] = $first[$key];
}

return
$diff;
}
?>

另一种尝试更简洁,但并非在所有情况下都能正常工作。
[email protected]
3年前
用于多个数组的递归差异比较,扩展了Gosh提供的解决方案。

<?php

function array_diff_assoc_recursive(array $array, array ...$arrays)
{
$func = function($array1, $array2) use (&$func){
$difference = [];
foreach (
$array1 as $key => $value) {
if (
is_array($value)) {
if (!isset(
$array2[$key]) || !is_array($array2[$key])) {
$difference[$key] = $value;
} else {
$new_diff = $func($value, $array2[$key]);
if (!empty(
$new_diff)) {
$difference[$key] = $new_diff;
}
}
} else {
if (!
array_key_exists($key, $array2) || $array2[$key] !== $value) {
$difference[$key] = $value;
}
}
}
return
$difference;
};
$diffs = $array;
foreach (
$arrays as $_array) {
$diffs = $func($diffs, $_array);
}
return
$diffs;
}

?>
Henry
9个月前
函数 array_diff_assoc_recursive($array1, $array2)
{
$array1Array = [];

foreach ($array1 as $key => $value) {
if (!is_array($value)) {
continue;
}
$array1Array[$key] = $value;
unset($array1[$key]);
}

$array2Array = [];

foreach ($array2 as $key => $value) {
if (!is_array($value)) {
continue;
}
$array2Array[$key] = $value;
unset($array2[$key]);
}

$diff = is_int(array_key_first($array1)) ? array_values(array_diff($array1, $array2)) : array_diff_assoc($array1, $array2);

foreach ($array1Array as $key => $value) {
if (isset($array2Array[$key])) {
$subDiff = array_diff_assoc_recursive($value, $array2Array[$key]);
if (count($subDiff) !== 0) {
$diff = array_merge($diff, is_int($key) ? [$subDiff] : [$key => $subDiff]);
}
} else {
$diff = array_merge($diff, is_int($key) ? [$value] : [$key => $value]);
}
}

return $diff;
}
[email protected]
2年前
接受多个 n 级数组作为参数的递归实现

```php
function recursiveDiff(...$arrays)
{
$first = array_shift($arrays);
$diff = [];

foreach ($first as $key => $value) {
$values = array_map(function ($arr) use ($key) {
if (is_array($arr) && !array_key_exists($key, $arr)) {
return null;
}

return isset($arr[$key]) ? $arr[$key] : null;
}, $arrs);

if (in_array($value, $values)) {
continue;
}

if (is_array($value)) {
array_unshift($values, $value);
$diff[$key] = call_user_func_array(__FUNCTION__, $values);
continue;
}

$diff[$key] = $first[$key];
}

return $diff;
}
```
nekto
2年前
PHP关联数组的键区分大小写,键“a”与键“A”不同。

<?php
$arr
= ["A" => 666];
var_dump($arr["a"]);
var_dump($arr["A"]);
?>

输出结果为
NULL
int(666)

同样,array_diff_assoc 函数对键的大小写敏感,键“A”不等于键“a”,它们会被认为是不同的。

<?php
// 下面的数组中,“a”和“A”的值相同,但键不同
// “b”的值不同
// “c”的值相同
$compareWhat = ["a" => 666, "b" => 666, "c" => 666, ];
$compareWith = ["A" => 666, "b" => 667, "c" => 666, ];

var_dump(array_diff_assoc($compareWhat, $compareWith));
?>

输出结果为
array(2) {
["a"]=> int(666)
["b"]=> int(666)
}

如果数组中值的顺序不同,结果的顺序也会不同,尽管结果本身基本相同。

<?php
// 与上面相同,但 $compareWhat 中 “b” 在 “a” 之前
$compareWhat = ["b" => 666, "a" => 666, "c" => 666, ];
$compareWith = ["A" => 666, "b" => 667, "c" => 666, ];

var_dump(array_diff_assoc($compareWhat, $compareWith));
?>

输出结果为
array(2) {
["b"]=> int(666)
["a"]=> int(666)
}
[email protected]
10 年前
这是一个我找了很久的函数,现在我创建了它,以便其他人如果需要也能找到它;]
<?php
function compare_two_object_recursive($object_1, $object_2, $object_1_Identifier = false, $object_2_Identifier = false){
$object1 = (array)$object_1;
$object2 = (array)$object_2;
$object3 = array();

$o1i = $object_1_Identifier ? $object_1_Identifier : 1;
$o2i = $object_2_Identifier ? $object_2_Identifier : 2;

foreach(
$object1 as $key => $value){
if(
is_object($object1[$key])){
$object1[$key] = (array)$object1[$key];
$object2[$key] = (array)$object2[$key];
$object3[$key] = (object)compare_two_object_recursive($object1[$key], $object2[$key], $o1i, $o2i);
}elseif(
is_array($object1[$key])){
$object3[$key] = compare_two_object_recursive($object1[$key], $object2[$key], $o1i, $o2i);
}else{
if(
$object1[$key] == $object2[$key]){
$object3[$key]['comparison_status'] = "SAME";
}else{
$object3[$key]['comparison_status'] = "NOT THE SAME";
$object3[$key][$o1i] = $object1[$key];
$object3[$key][$o2i] = $object2[$key];
}
}
}
return
$object3;
}
?>
[email protected]
6年前
另一个递归实现,没有if-else地狱,并且像原始版本一样具有多个参数。

<?php
function recursiveDiff() {
$arrs = func_get_args();
$diff = call_user_func_array('array_diff_assoc', $arrs);

foreach(
$diff as $key => $value) {
if (!
is_array($value))
continue;

$children = array_map(function($arr) use($key){
return
$arr[$key];
},
$arrs);

$diff[$key] = call_user_func_array(__FUNCTION__, $children);
}

return
$diff;
}
[email protected]
10 年前
[email protected]
我不得不使用您的函数,但它表明isset的使用无法区分NULL值和未设置的值。

这是一个处理此细微差别的版本。

<?php
function array_diff_assoc_recursive($array1, $array2)
{
$difference = NULL;
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
{
$new_diff = array_diff_assoc_recursive($value, $array2[$key]);
if(
$new_diff != FALSE)
{
$difference[$key] = $new_diff;
}
}
}
elseif(!
array_key_exists($key, $array2) || $array2[$key] != $value)
{
$difference[$key] = $value;
}
}
return !isset(
$difference) ? 0 : $difference;
}
?>

希望有帮助
弗朗索瓦
To Top