PHP Conference Japan 2024

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() 範例

只有當 (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 值的陣列。這是因為當陣列鍵不存在或設定為 null 時,!isset 為 true。

(抱歉變更了縮排樣式)
<?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
}
}
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
)
telefoontoestel at hotmail dot com
10 年前
先前的遞迴 array_diff_assoc 文章失敗,因為 isset 在包含 null 值的陣列元素上傳回 false。我更新了程式碼,使其也能比較 null 值。

<?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;
}
?>
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
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;
}
?>

[NOTE BY 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;
}

?>
tero dot lahtinen at iki dot fi
7 年前
如果值是無法轉換為字串的內容,array_diff_assoc 會失敗。
benjamin at moonfactory dot co dot jp
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" 值會被移除
?>
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 有很多元素或動態產生,這就最有意義。
news_yodpeirs at thoftware dot de
13 年前
一個相當簡單(但效率不高)的方法來比較第一層級具有非字串值的陣列
array_map('unserialize',array_diff_assoc(array_map('serialize',$arr1),array_map('serialize',$arr2)))
可能對除錯很有用(這是我使用它的目的)。
jrajpu10 at gmail dot com
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 程式設計師所預期的那樣是嚴格的依序排列。
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;
}
?>
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;
}
?>

另一個嘗試比較簡潔,但並非適用於所有情況。
angujomondi at gmail dot com
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 個月前
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;
}
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;
}
```
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)
}
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;
}
?>
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;
}
francois-php at ceonizme dot fr
10 年前
給 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;
}
?>

希望對您有幫助
François
To Top