For my application, I was using array_diff_assoc
, when I noticed it was returning the wrong value. I was using multidimensional arrays, therefore I needed a array_diff_assoc_recursive
method.
I Googled around and found a few, but they all only took 2 parameters. The official array_diff_assoc
can take an infinite number of params. I wanted mine to, so I wrote my own array_diff_assoc_recursive
function.
<?php
class Tools{
/**
* Recursive version of array_diff_assoc
* Returns everything from $a that is not in $b or the other arguments
*
* @param $a The array to compare from
* @param $b An array to compare against
* @param ... More arrays to compare against
*
* @return An array with everything from $a that not in $b or the others
*/
public static function array_diff_assoc_recursive($a, $b){
// Get all of the "compare against" arrays
$b = array_slice(func_get_args(), 1);
// Initial return value
$ret = array();
// Loop over the "to" array and compare with the others
foreach($a as $key=>$val){
// We should compare type first
$aType = gettype($val);
// If it's an array, we recurse, otherwise we just compare with "==="
$args = $aType === 'array' ? array($val) : true;
// Let's see what we have to compare to
foreach($b as $x){
// If the key doesn't exist or the type is different,
// then it's different, and our work here is done
if(!array_key_exists($key, $x) || $aType !== gettype($x[$key])){
$ret[$key] = $val;
continue 2;
}
// If we are working with arrays, then we recurse
if($aType === 'array'){
$args[] = $x[$key];
}
// Otherwise we just compare
else{
$args = $args && $val === $x[$key];
}
}
// This is where we call ourselves with all of the arrays we got passed
if($aType === 'array'){
$comp = call_user_func_array(array(get_called_class(), 'array_diff_assoc_recursive'), $args);
// An empty array means we are equal :-)
if(count($comp) > 0){
$ret[$key] = $comp;
}
}
// If the values don't match, then we found a difference
elseif(!$args){
$ret[$key] = $val;
}
}
return $ret;
}
}
I was wondering what you thought of my attempt. It seems to work ok for my application, and in the few tests I tried with it.
DEMO: http://ideone.com/5GZ8Tn
array_diff_assoc_recursive
method. I don't think I am still working on the project that this was used in. Though, as you've shown the code does need a bit of work to do what it's supposed to do. Maybe if I am bored later, I can try to fix it. Whatever I was using this for, it seemed to be ok there, but I don't remember exactly what this was being used for :-) \$\endgroup\$array_diff_assoc
does, but then digs into arrays and compares individual elements using the samearray_diff_assoc
logic... \$\endgroup\$array_diff_assoc
say "the values from array1 that are not present in any of the other arrays." So, if it finds the value in any of the comparative arrays, it's removed from the first array. With myarray_diff_assoc_recursive
method if it sees an array as a value, it calls itself again. I'd think that your data should just be[8,10]
... \$\endgroup\$