Intereting Posts

многомерная разность матриц php

У меня два многомерных массива, и я хочу разницу. Напр. Я взял двумерные два массива ниже

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

Проблемы, обнаруженные / исправленные

  1. Результат заполняется клавишами, которые не имеют разницы
  2. Если одно значение является массивом, а другое – нет, оно не учитывает разницу

Есть много случаев, когда исходные ответы не будут работать должным образом, поэтому я написал лучшее решение. Одна из проблем заключалась в том, что если вы удалили свойство в массиве 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