array_diff_assoc

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

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

说明

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

比较 arrayarrays,并返回差集。与 array_diff() 不同,此函数还会在比较中使用数组键。

参数

array

要比较的数组

arrays

要比较的数组

返回值

返回一个 array,包含 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() 范例

来自 key => value 对的两个值仅在 (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 个注释

62
Giosh
11 年前
"chinello at gmail dot com"(以及其他)的 array_diff_assoc_array 对于包含 null 值的数组将不起作用。这是因为当数组键不存在或设置为 null 时,!isset 为真。

(抱歉,缩进样式已更改)
<?php
function array_diff_assoc_recursive($array1, $array2) {
$difference=array();
foreach(
$array1 as $key => $value) {
if(
is_array($value) ) {
if( !isset(
$array2[$key]) || !is_array($array2[$key]) ) {
$difference[$key] = $value;
} else {
$new_diff = array_diff_assoc_recursive($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;
}
?>

这是一个例子(注意输出中的索引 '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
}
}
13
contact at pascalopitz dot 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));
?>

输出

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

<?php
function array_diff_assoc_recursive($array1, $array2)
{
foreach(
$array1 as $key => $value)
{
if(
is_array($value))
{
if(!isset(
$array2[$key]))
{
$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;
}
?>
17
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
)
11
chinello at gmail dot com
17 年前
以下代码将递归地执行 array_diff_assoc,这将计算多维级别的差异。如果键不存在,并且 error_reporting 设置为 E_ALL,则不会显示任何通知。

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

[注意:这是来自先前删除的笔记的联合努力。贡献者包括(Michael Johnson)、(jochem AT iamjochem DAWT com)、(sc1n AT yahoo DOT com) 和 (anders DOT carlsson AT mds DOT mdh DOT se)。]
5
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;
}

?>
4
tero dot lahtinen at iki dot fi
6 年前
如果值是无法转换为字符串的东西,array_diff_assoc 会失败。
5
benjamin at moonfactory dot co dot jp
19 年前
大家好,
对于 php 版本 < 4.3...

<?php
/**
* array_diff_assoc for version < 4.3
**/
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 ;
}
}

?>
6
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" 值被移除
?>
3
carl at thep dot lu dot se
21 年前
如果您知道键但不确定值,可以这样做来取消设置数组中的元素

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

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

当然,如果 $b 具有多个元素或动态生成,这样做最有意义。
1
news_yodpeirs at thoftware dot de
13 年前
一种非常简单(但效率不高)的方法来比较具有非字符串值的数组的第一级
array_map('unserialize',array_diff_assoc(array_map('serialize',$arr1),array_map('serialize',$arr2)))
可能对调试很有用(这就是我用来调试的)。
1
jrajpu10 at gmail dot com
15 年前
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 程序员预期的严格顺序排列。
2
cedric at daneel dot net
17 年前
要比较 n 维数组之间的差异,只需使用以下代码

<?php
function array_diff_values($tab1, $tab2)
{
$result = array();
foreach(
$tab1 as $values) if(! in_array($values, $tab2)) $result[] = $values;
return
$result;
}
?>
2
spark dot crz at gmail dot com
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;
}
?>

另一种尝试更简洁,但并不适用于所有情况。
1
angujomondi at gmail dot com
3 年前
用于多个数组的递归 diff,扩展了 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;
}

?>
0
Henry
5 个月前
function 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;
}
0
folurinyinka at gmail dot com
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;
}
```
-1
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" 并且会被 diff

<?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
// 与上面相同,但 "b" 在 $compareWhat 中位于 "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)
}
0
shadow_games at abv dot bg
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;
}
?>
-2
spark dot crz at gmail dot com
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;
}
-5
francois-php at ceonizme dot fr
9 年前
给 chinello at gmail dot com
我不得不使用你的函数,但它显示 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