php 多维数组差异php
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12246039/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
multidimensional array difference php
提问by kcssm
I have two multidimensional arrays and I want the difference. For eg. I have taken 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 key difference of these two arrays. I have tried array_diff_key() but it doesnot work for multidimensional.
现在我想要这两个数组的主要区别。我尝试过 array_diff_key() 但它不适用于多维。
array_diff_key($array1, $array2)
I want the output as following
我希望输出如下
//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 it and answer. Thank you.
如果您认为我的问题是真实的,请接受并回答。谢谢你。
EDIT
编辑
Now if the second array is
现在如果第二个数组是
$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
)
)
回答by Zaheer Abbass
Please check if I understand you correctly then this code snippet can help to you solve your problem. I have tested it for your specified problem only. if there are other testcases for which you want to run this, you can tell me to adjust 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: added tweak to code.
编辑:添加了对代码的调整。
回答by Jonny Alexander
this solution ah been very helpful to me I hope can help them in something, no matter what the array are in disarray.
这个解决方案啊对我很有帮助我希望可以帮助他们一些东西,无论什么阵列都乱七八糟。
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>";
回答by bernhardh
There are a lot of cases, where original answers will not work properly, so I wrote a better solution. One of the problems was, that if you deleted a property in array 2, the other functions didn't recognized it.
有很多情况,原始答案无法正常工作,所以我写了一个更好的解决方案。问题之一是,如果您删除了数组 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;
}
I have also added test cases to check result:
我还添加了测试用例来检查结果:
- Here you can find result for my function: http://sandbox.onlinephpfunctions.com/code/3bf7b032f772f8a4d184ca4151de9c3e9e9a58bc
- Here you can find result for the accepted answer: http://sandbox.onlinephpfunctions.com/code/88efa3feb5f28bf256b5a220bd881d4a4a04130f
- 在这里你可以找到我的函数的结果:http: //sandbox.onlinephpfunctions.com/code/3bf7b032f772f8a4d184ca4151de9c3e9e9a58bc
- 在这里您可以找到已接受答案的结果:http: //sandbox.onlinephpfunctions.com/code/88efa3feb5f28bf256b5a220bd881d4a4a04130f
As you can see, my fuctions delivers better results.
如您所见,我的功能提供了更好的结果。
回答by Augwa
I know this thread is kind of old, however I ran into a few problems with the original solution. So here is my solution of 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;
}
Problems Encountered / Fixed
遇到/修复的问题
- Result populates with keys that have no difference
- If one value is an array and the other is not, it doesn't consider it a difference
- 结果用没有区别的键填充
- 如果一个值是一个数组而另一个不是,它不认为它有区别
回答by mikeytown2
Almost a copy of @bernhardh's answer but posting here because my edit was rejected. Uses + instead of array_merge as array_merge will reindex array causing issues with indexed arrays.
几乎是@bernhardh 答案的副本,但在此处发布是因为我的编辑被拒绝。使用 + 而不是 array_merge,因为 array_merge 将重新索引数组,导致索引数组出现问题。
/**
* 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;
}
回答by Alex Rabinovich
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.
一个更好的函数,就像原来的 array_diff 一样工作。
将 array1 与一个或多个其他数组进行比较,并递归返回 array1 中不存在于任何其他数组中的值。
<?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
回答by Faiz Mohamed Haneef
$out = array_diff_assoc_recursive($array1, $array2);
The solution requires recursing values of array which may themselves 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;
}
回答by Lebnik
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
)
)
回答by kcssm
One small tweak to @Zaheer Abbass solution, I got the result I wanted. Thank you very much Zaheer. Here is the final code that i used.
对@Zaheer Abbass 解决方案的一个小调整,我得到了我想要的结果。非常感谢 Zaheer。这是我使用的最终代码。
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;
}
回答by fdrv
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;
}

