Multidimensional matrix difference php

I have two multidimensional arrays and I want the difference. E.g. I took two-dimensional two arrays below

$array1 = Array ( [a1] => Array ( [a_name] => aaaaa [a_value] => aaa ) [b1] => Array ( [b_name] => bbbbb [b_value] => bbb ) [c1] => Array ( [c_name] => ccccc [c_value] => ccc ) ) $array2 = Array ( [b1] => Array ( [b_name]=> zzzzz ) ) 

Now I want the difference in the keys of these two arrays. I tried array_diff_key (), but it does not work for multidimensional.

 array_diff_key($array1, $array2) 

I want the result to be as follows

 //output $array1 = Array ( [a1] => Array ( [a_name] => aaaaa [a_value] => aaa ) [b1] => Array ( [b_value] => bbb ) [c1] => Array ( [c_name] => ccccc [c_value] => ccc ) ) 

If you think my question is genuine, please accept and answer. Thanks.

EDIT

Now if the second array

 $array2 = Array( [b1] => zzzzz) 

The result should be

 $array1 = Array ( [a1] => Array ( [a_name] => aaaaa [a_value] => aaa ) [c1] => Array ( [c_name] => ccccc [c_value] => ccc ) ) 
+4
source share
11 answers

Please check if I understand you correctly, this piece of code will help you solve your problem. I tested it only for the indicated problem. if there are other test tags for which you want to run this, you can tell me to configure the code.

 $a1 = array( 'a1' => array('a_name' => 'aaa', 'a_value' => 'aaaaa'), 'b1' => array('b_name' => 'bbb', 'b_value' => 'bbbbbb'), 'c1' => array('c_name' => 'ccc', 'c_value' => 'cccccc') ); $a2 = array( 'b1' => array('b_name' => 'zzzzz'), ); $result = check_diff_multi($a1, $a2); print '<pre>'; print_r($result); print '</pre>'; function check_diff_multi($array1, $array2){ $result = array(); foreach($array1 as $key => $val) { if(isset($array2[$key])){ if(is_array($val) && $array2[$key]){ $result[$key] = check_diff_multi($val, $array2[$key]); } } else { $result[$key] = $val; } } return $result; } 

EDIT: code setting added.

+8
source

this solution was very useful for me, I hope they can help them with something, no matter the array is in a mess.

 function your_array_diff($arraya, $arrayb) { foreach ($arraya as $keya => $valuea) { if (in_array($valuea, $arrayb)) { unset($arraya[$keya]); } } return $arraya; } $a1 = Array ( "0" => Array ( "Empresa" => "TMC01", "Paga" => "13/01/2015", "ID" => "M2", "Valor" => "200", "Nombre" => "BONI" ), "1" => Array ( "Empresa" => "TMC01", "Paga" => "13/01/2015", "ID" => "M1", "Valor" => "100", "Nombre" => "SUELDO" ) ); $b1 = Array ( "0" => Array ( "Empresa" => "TMC01", "Paga" => "13/01/2015", "ID" => "M1", "Valor" => "100", "Nombre" => "SUELDO" ), "1" => Array ( "Empresa" => "TMC01", "Paga" => "13/01/2015", "ID" => "M2", "Valor" => "200", "Nombre" => "BONI" ) ); $resultado = your_array_diff($a1, $b1); echo "<pre>"; echo print_r($resultado); echo "</pre>"; 
+3
source

I know this thread is old, however I ran into several problems with the original solution. So here is my solution to the problem.

 private function array_diff_recursive($array1, $array2){ $result = []; foreach($array1 as $key => $val) { if(array_key_exists($key, $array2)){ if(is_array($val) || is_array($array2[$key])) { if (false === is_array($val) || false === is_array($array2[$key])) { $result[$key] = $val; } else { $result[$key] = $this->array_diff_recursive($val, $array2[$key]); if (sizeof($result[$key]) === 0) { unset($result[$key]); } } } } else { $result[$key] = $val; } } return $result; } 

Issues Detected / Corrected

  • The result is filled with keys that do not matter.
  • If one value is an array and the other is not, it does not consider the difference
+1
source

There are many cases where the original answers will not work properly, so I wrote a better solution. One of the problems was that if you deleted the property in array 2, the other functions did not recognize it.

 function check_diff_multi($array1, $array2){ $result = array(); foreach($array1 as $key => $val) { if(is_array($val) && isset($array2[$key])) { $tmp = check_diff_multi($val, $array2[$key]); if($tmp) { $result[$key] = $tmp; } } elseif(!isset($array2[$key])) { $result[$key] = null; } elseif($val !== $array2[$key]) { $result[$key] = $array2[$key]; } if(isset($array2[$key])) { unset($array2[$key]); } } $result = array_merge($result, $array2); return $result; } 

I also added test cases to verify the result:

As you can see, my fuctions provide better results.

+1
source

One small tweak for @Zaheer Abbass solution, I got the result I wanted. Thanks a lot to Sacher. Here is the last code I used.

 function check_diff_multi($array1, $array2){ $result = array(); foreach($array1 as $key => $val) { if(isset($array2[$key])){ if(is_array($val) && is_array($array2[$key])){ $result[$key] = check_diff_multi($val, $array2[$key]); } } else { $result[$key] = $val; } } return $result; } 
0
source

So, if you have arrays with empty values ​​or with empty arrays.

 private function check_diff_multi($array1, $array2){ $result = array(); foreach($array1 as $key => $val) { if(array_key_exists($key,$array2)){ if(is_array($val) && is_array($array2[$key]) && !empty($val)){ $result[$key] = $this->check_diff_multi($val, $array2[$key]); } } else { $result[$key] = $val; } } return $result; } 
0
source
 $out = array_diff_assoc_recursive($array1, $array2); 

The solution requires recursive array values, which themselves can be arrays.

 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; } 
0
source

Try the function:

 <?php $input = ['blue' => 1, 'white' => ['purple' => 4, 'green' => 3], 'red' => 2]; $filter = ['blue' => 6, 'white' => ['yellow' => 7, 'green' => 5], 'red' => 2]; /** * @param array $input * @param array $filter * @return array */ function multidimensionalArrayDiffKey(array $input, array $filter) { if ($diff = array_diff_key($input, $filter)){ return $diff; }else{ foreach($input as $key => $value){ if(is_array($value) && $diff = multidimensionalArrayDiffKey($value, $filter[$key])){ return [$key => $diff]; } } } return []; } print_r(multidimensionalArrayDiffKey($input, $filter)); 

Result:

 Array ( [white] => Array ( [purple] => 4 ) ) 
0
source

For multidimensional arrays, array_diff_assoc works better than array_diff in some cases. I had a problem with array_diff where it was not able to distinguish 1 or 0 as a value (maybe some other index had the same value), so array_diff_assoc solved it, since it also checks indexes. Only for future users who may encounter the same problem.

0
source
 - A better function that works just like the original array_diff: - Compares array1 against one or more other arrays and returns the values in array1 that are not present in any of the other arrays recursively. <?php function md_array_diff(array $array1, array $array2, array $_ = null) { $diff = []; $args = array_slice(func_get_args(), 1); foreach ($array1 as $key => $value) { foreach ($args as $item) { if (is_array($item)) { if (array_key_exists($key, $item)) { if (is_array($value) && is_array($item[$key])) { $tmpDiff = md_array_diff($value, $item[$key]); if (!empty($tmpDiff)) { foreach ($tmpDiff as $tmpKey => $tmpValue) { if (isset($item[$key][$tmpKey])) { if (is_array($value[$tmpKey]) && is_array($item[$key][$tmpKey])) { $newDiff = array_diff($value[$tmpKey], $item[$key][$tmpKey]); } else if ($value[$tmpKey] !== $item[$key][$tmpKey]) { $newDiff = $value[$tmpKey]; } if (isset($newDiff)) { $diff[$key][$tmpKey] = $newDiff; } } else { $diff[$key][$tmpKey] = $tmpDiff; } } } } else if ($value !== $item[$key]) { $diff[$key] = $value; } } else { $diff[$key] = $value; } } } } return $diff; } $arr1 = [ "A" => [ "A1" => ['A1-0', 'A1-1', 'A1-2', 'A1-3'], "A2" => ['A2-0', 'A2-1', 'A2-2', 'A2-3'], "A3" => ['A3-0', 'A3-1', 'A3-2', 'A3-3'] ], "B" => [ "B1" => ['B1-0', 'B1-1', 'B1-2', 'B1-3'], "B2" => ['B2-0', 'B2-1', 'B2-2', 'B2-3'], "B3" => ['B3-0', 'B3-1', 'B3-2', 'B3-3'] ], 'C' => 123 ]; $arr2 = [ "A" => [ "A1" => ['A1-1', 'A1-2', 'A1-3'], "A2" => ['A2-0', 'A2-1', 'A2-2', 'A2-3'], "A3" => ['A3-0', 'A3-1', 'A3-2'] ], "B" => [ "B1" => ['B1-0', 'B1-2', 'B1-3'], "B2" => ['B2-0', 'B2-1', 'B2-2', 'B2-3'], "B3" => ['B3-0', 'B3-1', 'B3-3'] ] ]; $arr3 = [ "A" => [ "A1" => ['A1-0', 'A1-1', 'A1-2', 'A1-3'], "A2" => ['A2-0', 'A2-1', 'A2-2', 'A2-3'], "A3" => ['A3-0', 'A3-1', 'A3-2'] ], "B" => [ "B1" => ['B1-0', 'B1-2', 'B1-3'], "B2" => ['B2-0', 'B2-1', 'B2-2', 'B2-3'], "B3" => ['B3-0', 'B3-1', 'B3-3'] ] ]; $diff = md_array_diff($arr1, $arr2, $arr3); ?> Will Output: array (size=3) 'A' => array (size=2) 'A1' => array (size=1) 0 => string 'A1-0' (length=4) 'A3' => array (size=1) 3 => string 'A3-3' (length=4) 'B' => array (size=2) 'B1' => array (size=1) 1 => string 'B1-1' (length=4) 'B3' => array (size=1) 2 => string 'B3-2' (length=4) 'C' => int 123 
0
source

Almost a copy of @bernhardh's answer, but published here because my editing was rejected. Uses + instead of array_merge, since array_merge will be a reindex array, causing problems with indexed arrays.

 /** * Given 2 arrays see what has changed when comparing defaults to the new values. * * @param array $defaults * Array of default values. * @param mixed $new_values * Array of new values. * * @return array * Nested array strucutre; only the diff. */ function array_diff_multi(array $defaults, $new_values) { $result = array(); foreach ($defaults as $key => $val) { if (is_array($val) && isset($new_values[$key])) { $tmp = array_diff_multi($val, $new_values[$key]); if ($tmp) { $result[$key] = $tmp; } } elseif (!isset($new_values[$key])) { $result[$key] = NULL; } elseif ($val != $new_values[$key]) { $result[$key] = $new_values[$key]; } if (isset($new_values[$key])) { unset($new_values[$key]); } } $result = $result + $new_values; return $result; } 
0
source

Source: https://habr.com/ru/post/1432048/


All Articles