array_diff_assoc

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

array_diff_assocOblicza różnicę między tablicami z dodatkowym sprawdzaniem kluczy

Opis

array_diff_assoc ( array $tablica1 , array $tablica2 [, array $... ] ) : array

Porównuje tablica1 z tablica2 i zwraca różnicę. W przeciwieństwie do array_diff(), porównywane są także klucze tablic.

Parametry

tablica1

Tablica do porównania

tablica2

Tablica, z którą porównujemy

...

Więcej tablic do porównania

Zwracane wartości

Zwraca tablicę zawierającą wszystkie wartości z tablica1, które nie są obecne w żadnej z innych tablic.

Przykłady

Przykład #1 Przykład użycia array_diff_assoc()

W tym przykładzie możesz zobaczyć, że para "a" => "green" jest obecna w obu tablicach i dlatego nie jest wyświetlana przez funkcję W odróżnieniu od 0 => "red", które jest wyświetlane, ponieważ w drugiej tablicy "red" ma klucz, którym jest 1.

<?php
$tablica1 
= array("a" => "green""b" => "brown""c" => "blue""red");
$tablica2 = array("a" => "green""yellow""red");
$wynik array_diff_assoc($tablica1$tablica2);
print_r($tablica);
?>

Powyższy przykład wyświetli:

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

Przykład #2 Przykład użycia array_diff_assoc()

Wartości z par klucz => wartość są uznawane za jednakowe, tylko gdy (string) $elem1 === (string) $elem2 . Innymi słowy, stosowane jest ścisłe porównanie, a więc reprezentacja w postaci ciągu znaków musi być jednakowa.

<?php
$tablica1 
= array(012);
$tablica2 = array("00""01""2");
$wynik array_diff_assoc($tablica1$tablica2);
print_r($wynik);
?>

Powyższy przykład wyświetli:

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

Notatki

Informacja: Ta funkcja sprawdza tylko pierwszy wymiar tablicy wielowymiarowej. Oczywiście można porównać głębsze wymiary używając array_diff_assoc($array1[0], $array2[0]);.

Informacja: Upewnij się, że przekazujesz argumenty z odpowiedniej kolejności, gdy porównujesz podobne tablice z większą ilością kluczy. Nowa tablica powinna być przekazana pierwsza.

Zobacz też:

  • array_diff() - Zwraca różnicę między tablicami
  • array_diff_uassoc() - Oblicza różnicę tablic z dodatkowym sprawdzeniem indeksu wykonywanym przez podaną przez użytkownika funkcję
  • array_udiff_assoc() - Computes the difference of arrays with additional index check, compares data by a callback function
  • array_udiff_uassoc() - Computes the difference of arrays with additional index check, compares data and indexes by a callback function
  • array_intersect() - Zwraca przecięcie tablic
  • array_intersect_assoc() - Wylicza przecięcie tablic z dodatkowym sprawdzaniem indeksów

add a note add a note

User Contributed Notes 17 notes

up
48
Giosh
7 years ago
The array_diff_assoc_array from "chinello at gmail dot com" (and others) will not work for arrays with null values. That's because !isset is true when an array key doesn't exists or is set to null.

(sorry for the changed indent-style)
<?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;
}
?>

And here an example (note index 'b' in the output):
<?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
  }
}
up
16
Michael Richey
7 years ago
If you're looking for a true array_diff_assoc, comparing arrays to determine the difference between two, finding missing values from both, you can use this along with 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));
// returns:
array
(
    [c] => 3
)

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

print_r(array_merge(array_diff_assoc($a,$b),array_diff_assoc($b,$a)));
// returns
array
(
    [c] => 3
    [d] => 4
)
up
9
contact at pascalopitz dot com
13 years ago
The direction of the arguments does actually make a difference:

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

echoes:

Array
(
)
Array
(
    [g] => g
)
up
5
telefoontoestel at hotmail dot com
6 years ago
an earlier post for recursive array_diff_assoc failed because isset returned false on an array element containing a null value. I updated the code so it compares null values too.

<?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;
}
?>
up
11
chinello at gmail dot com
13 years ago
The following will recursively do an array_diff_assoc, which will calculate differences on a multi-dimensional level.  This not display any notices if a key don't exist and if error_reporting is set to 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: This is a combination of efforts from previous notes deleted.  Contributors included (Michael Johnson), (jochem AT iamjochem DAWT com), (sc1n AT yahoo DOT com), and (anders DOT carlsson AT mds DOT mdh DOT se).]
up
6
benjamin at moonfactory dot co dot jp
15 years ago
Hi all,
For php versions < 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 ;
    }
}

?>
up
4
cedric at daneel dot net
13 years ago
To diff between n-dimensional array, juste use this :

<?php
function array_diff_values($tab1, $tab2)
    {
   
$result = array();
    foreach(
$tab1 as $values) if(! in_array($values, $tab2)) $result[] = $values;
    return
$result;
    }
?>
up
4
carl at thep dot lu dot se
17 years ago
To unset elements in an array if you know the keys but not the values, you can do:

<?php
$a
= array("foo", "bar", "baz", "quux");
$b = array(1, 3); // Elements to get rid of

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

Of course this makes most sense if $b has many elements or is dynamically generated.
up
4
Alexander Podgorny
14 years ago
NOTE: the diff_array also removes all the duplicate values that match to the values in the second array:

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

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

   
// yields: array("b","c") the duplicate "a" values are removed
?>
up
1
jrajpu10 at gmail dot com
11 years ago
array_diff_assoc can also be used to find the duplicates in an array

<?php
$arr
= array('1','2','3','4','3','2','5');
$uniques = array_unique($arr);
// array_diff will not work here, array_diff_assoc works as it takes the key // in account.
$dups = array_diff_assoc($arr, $uniques);

print_r($dups);
?>

Note: The index of the $dups is not in strict sequential order as expected by C programmer.
up
1
news_yodpeirs at thoftware dot de
9 years ago
A quite simple (yet not very efficient) way to compare the first level of arrays which have values that are not strings:
array_map('unserialize',array_diff_assoc(array_map('serialize',$arr1),array_map('serialize',$arr2)))
Might be useful for debugging (that's what I use it for).
up
1
spark dot crz at gmail dot com
2 years ago
Recursive implementation accepting multiple n-level-arrays as parameters:

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

The other attempt was cleaner but didn't work for all cases.
up
2
dev5er6 at gmail dot com
6 years ago
Works more like the original function:

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

?>
up
1
shadow_games at abv dot bg
6 years ago
there is a functiont that i searched long enough now i have created it so someone else to find it if he need it ;]
<?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;
    }
?>
up
0
tero dot lahtinen at iki dot fi
2 years ago
array_diff_assoc will fail, if a value is something that can not be converted to a string.
up
-1
spark dot crz at gmail dot com
2 years ago
Yet another recursive implementation, without if-else hell and with multiple parameters just like the original.

<?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;
}
up
-4
francois-php at ceonizme dot fr
6 years ago
to chinello at gmail dot com
I've had to use your function but it showed that the use of isset can't differentiate the NULL values from not setted values.

Here's a version that takes care of this subtility.

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

Hope that helps
François
To Top