У меня два многомерных массива, и я хочу разницу. Напр. Я взял двумерные два массива ниже
$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 ) )
Теперь я хочу ключевое различие этих двух массивов. Я попытался array_diff_key (), но он не работает для многомерного.
array_diff_key($array1, $array2)
Я хочу, чтобы результат был следующим
//output $array1 = Array ( [a1] => Array ( [a_name] => aaaaa [a_value] => aaa ) [b1] => Array ( [b_value] => bbb ) [c1] => Array ( [c_name] => ccccc [c_value] => ccc ) )
Если вы считаете, что мой вопрос является подлинным, пожалуйста, примите его и ответьте. Спасибо.
РЕДАКТИРОВАТЬ
Теперь, если второй массив
$array2 = Array( [b1] => zzzzz)
Результат должен быть
$array1 = Array ( [a1] => Array ( [a_name] => aaaaa [a_value] => aaa ) [c1] => Array ( [c_name] => ccccc [c_value] => ccc ) )
Пожалуйста, проверьте, правильно ли я вас понимаю, этот фрагмент кода поможет вам решить вашу проблему. Я тестировал его только для указанной проблемы. если есть другие тестовые теги, для которых вы хотите запустить это, вы можете сказать мне настроить код.
$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: добавлена настройка кода.
это решение было очень полезно для меня, я надеюсь, что они могут помочь им в чем-то, независимо от того, что массив находится в беспорядке.
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>";
с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>";
Я знаю, что эта ветка вроде старой, однако я столкнулся с несколькими проблемами с оригинальным решением. Итак, вот мое решение проблемы.
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; }
с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; }
Проблемы, обнаруженные / исправленные
Есть много случаев, когда исходные ответы не будут работать должным образом, поэтому я написал лучшее решение. Одна из проблем заключалась в том, что если вы удалили свойство в массиве 2, другие функции не узнали его.
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; }
с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; }
Я также добавил тестовые примеры для проверки результата:
Как вы можете видеть, мои fuctions обеспечивают лучшие результаты.
Одна небольшая настройка для решения @ Захера Аббаса, я получил результат, который хотел. Большое спасибо Захеру. Вот последний код, который я использовал.
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; }
Поэтому, если у вас есть массивы с пустыми значениями или с пустыми массивами.
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; }
$out = array_diff_assoc_recursive($array1, $array2);
Решение требует рекурсивных значений массива, которые сами могут быть массивами.
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; }
Попробуйте выполнить функцию:
<?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));
Результат:
Array ( [white] => Array ( [purple] => 4 ) )
Для многомерных массивов array_diff_assoc
работает лучше, чем array_diff
в некоторых случаях. У меня возникла проблема с array_diff
где он не смог отличить 1 или 0 как значение (возможно, какой-то другой индекс имел такое же значение), поэтому array_diff_assoc
решил его, так как он также проверяет индексы. Только для будущих пользователей, которые могут столкнуться с одной и той же проблемой.
- 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