如何比较和合并两个多维数组
How to compare and later merge two multidimensional arrays
我正在尝试通过以下方式合并两个多维数组(示例数组只是示例,真实的数组很长并且有数千项):
$array_a:
[0] => Array
(
[date] => 2018-02-25 15:12
[request] => 0
)
[1] => Array
(
[date] => 2018-02-25 15:13
[request] => 0
)
[2] => Array
(
[date] => 2018-02-25 15:14
[request] => 0
)
[3] => Array
(
[date] => 2018-02-25 15:15
[request] => 0
)
$array_b:
[0] => Array
(
[date] => 2018-02-25 15:12
[request] => 11
)
[1] => Array
(
[date] => 2018-02-25 15:13
[request] => 5
)
[2] => Array
(
[date] => 2018-02-25 15:15
[request] => 2
)
需要的结果:
[0] => Array
(
[date] => 2018-02-25 15:12
[request] => 11
)
[1] => Array
(
[date] => 2018-02-25 15:13
[request] => 5
)
[2] => Array
(
[date] => 2018-02-25 15:14
[request] => 0
)
[3] => Array
(
[date] => 2018-02-25 15:15
[request] => 2
)
有吗?谢谢
一种方法:
foreach($a as $v) {
$res[$v['date']] = $v['request'];
}
foreach($b as $v) {
if(isset($res[$v['date']])) {
if($v['request'] > $res[$v['date']])
$res[$v['date']] = $v['request'];
} else {
$res[$v['date']] == $v['request'];
}
}
foreach($res as $k=>$v)
$out[] = array("date" => $k, "request" => $v);
其中 $a
和 $b
是您的数组,$out
是最终结果。
工作原理:
因为我们正在比较日期并且我们知道它们是唯一的,所以我们将它们放入一个临时数组(在我的例子中 $res
)作为元素的键(数组的键是唯一的)。对于每个元素的值,我们比较请求的值并存储较大的值。
因此,第一个 foreach
循环遍历第一个数组并以以下形式将元素添加到 $res
:
$res['2018-02-25 15:12'] = 0;
第二个 foreach
循环遍历第二个数组的所有元素,但是,在这里我们还想确保我们对请求使用更大的值。
所以这是,if
逻辑检查元素是否存在,如果存在 - 为请求获取更大的值并将其存储到日期。如果不是 - 它完全按照它在第一个 foreach
循环中所做的那样(创建新元素)。
最后,我们想把数组放在一起看起来像什么,所以我们遍历 $res
和 re-create 数组,就像原来的两个一样。结果 $out
包含您请求的内容。
如果你必须添加值,你可以使用这样的东西:
$out = [];
// create new array using date as key, "object" as value.
foreach ($arr1 as $itm) {
$out[$itm['date']] = $itm;
}
// foreach each element of the second array,
foreach ($arr2 as $itm) {
// if it doesn't exists in the out array, simply add it
if (!isset($out[$itm['date']])) $out[$itm['date']] = $itm ;
// otherwise, add request to the first
else $out[$itm['date']]['request'] += $itm['request'];
}
ksort($out); // Sort by date (Optional)
$out = array_values($out); // get values to remove dates from keys
print_r($out);
输出:
Array
(
[0] => Array
(
[date] => 2018-02-25 15:12
[request] => 11
)
[1] => Array
(
[date] => 2018-02-25 15:13
[request] => 5
)
[2] => Array
(
[date] => 2018-02-25 15:14
[request] => 0
)
[3] => Array
(
[date] => 2018-02-25 15:15
[request] => 2
)
)
我可以给你结果,但是我不知道回调主体中的逻辑。
$array_c = array_values(array_reduce(array_merge($a, $b), function($carry, $item) {
$carry[$item['date']] = $item;
return $carry;
}, []));
我正在做的是组合数组(它们都是子集,所以没有内在冲突),然后我通过 "reduce down" 到数组键 > 值对,键是date/time,值是集合。这给出了将每个 date/time 合并到该数组中相同键的效果。这种情况下的回调只是 "remembers" 最后遇到的 date/time 块,因此是 "not sure what's needed" 问题。
最后,我得到了一个版本的数组,其中 date/times 替换为索引 (array_values()
)。这也很有趣,因为如果将 array_values()
调用移到以后,按日期排序将相当容易。
这给出:
array(4) {
[0]=>
array(2) {
["date"]=>
string(16) "2018-02-25 15:12"
["request"]=>
int(11)
}
[1]=>
array(2) {
["date"]=>
string(16) "2018-02-25 15:13"
["request"]=>
int(5)
}
[2]=>
array(2) {
["date"]=>
string(16) "2018-02-25 15:14"
["request"]=>
int(0)
}
[3]=>
array(2) {
["date"]=>
string(16) "2018-02-25 15:15"
["request"]=>
int(2)
}
}
可以做不同的事情,比如只保留第一个,或者添加每个请求(它们在第一个数组中都是零)。不过机制应该是一样的。
我正在尝试通过以下方式合并两个多维数组(示例数组只是示例,真实的数组很长并且有数千项):
$array_a:
[0] => Array
(
[date] => 2018-02-25 15:12
[request] => 0
)
[1] => Array
(
[date] => 2018-02-25 15:13
[request] => 0
)
[2] => Array
(
[date] => 2018-02-25 15:14
[request] => 0
)
[3] => Array
(
[date] => 2018-02-25 15:15
[request] => 0
)
$array_b:
[0] => Array
(
[date] => 2018-02-25 15:12
[request] => 11
)
[1] => Array
(
[date] => 2018-02-25 15:13
[request] => 5
)
[2] => Array
(
[date] => 2018-02-25 15:15
[request] => 2
)
需要的结果:
[0] => Array
(
[date] => 2018-02-25 15:12
[request] => 11
)
[1] => Array
(
[date] => 2018-02-25 15:13
[request] => 5
)
[2] => Array
(
[date] => 2018-02-25 15:14
[request] => 0
)
[3] => Array
(
[date] => 2018-02-25 15:15
[request] => 2
)
有吗?谢谢
一种方法:
foreach($a as $v) {
$res[$v['date']] = $v['request'];
}
foreach($b as $v) {
if(isset($res[$v['date']])) {
if($v['request'] > $res[$v['date']])
$res[$v['date']] = $v['request'];
} else {
$res[$v['date']] == $v['request'];
}
}
foreach($res as $k=>$v)
$out[] = array("date" => $k, "request" => $v);
其中 $a
和 $b
是您的数组,$out
是最终结果。
工作原理:
因为我们正在比较日期并且我们知道它们是唯一的,所以我们将它们放入一个临时数组(在我的例子中 $res
)作为元素的键(数组的键是唯一的)。对于每个元素的值,我们比较请求的值并存储较大的值。
因此,第一个 foreach
循环遍历第一个数组并以以下形式将元素添加到 $res
:
$res['2018-02-25 15:12'] = 0;
第二个 foreach
循环遍历第二个数组的所有元素,但是,在这里我们还想确保我们对请求使用更大的值。
所以这是,if
逻辑检查元素是否存在,如果存在 - 为请求获取更大的值并将其存储到日期。如果不是 - 它完全按照它在第一个 foreach
循环中所做的那样(创建新元素)。
最后,我们想把数组放在一起看起来像什么,所以我们遍历 $res
和 re-create 数组,就像原来的两个一样。结果 $out
包含您请求的内容。
如果你必须添加值,你可以使用这样的东西:
$out = [];
// create new array using date as key, "object" as value.
foreach ($arr1 as $itm) {
$out[$itm['date']] = $itm;
}
// foreach each element of the second array,
foreach ($arr2 as $itm) {
// if it doesn't exists in the out array, simply add it
if (!isset($out[$itm['date']])) $out[$itm['date']] = $itm ;
// otherwise, add request to the first
else $out[$itm['date']]['request'] += $itm['request'];
}
ksort($out); // Sort by date (Optional)
$out = array_values($out); // get values to remove dates from keys
print_r($out);
输出:
Array
(
[0] => Array
(
[date] => 2018-02-25 15:12
[request] => 11
)
[1] => Array
(
[date] => 2018-02-25 15:13
[request] => 5
)
[2] => Array
(
[date] => 2018-02-25 15:14
[request] => 0
)
[3] => Array
(
[date] => 2018-02-25 15:15
[request] => 2
)
)
我可以给你结果,但是我不知道回调主体中的逻辑。
$array_c = array_values(array_reduce(array_merge($a, $b), function($carry, $item) {
$carry[$item['date']] = $item;
return $carry;
}, []));
我正在做的是组合数组(它们都是子集,所以没有内在冲突),然后我通过 "reduce down" 到数组键 > 值对,键是date/time,值是集合。这给出了将每个 date/time 合并到该数组中相同键的效果。这种情况下的回调只是 "remembers" 最后遇到的 date/time 块,因此是 "not sure what's needed" 问题。
最后,我得到了一个版本的数组,其中 date/times 替换为索引 (array_values()
)。这也很有趣,因为如果将 array_values()
调用移到以后,按日期排序将相当容易。
这给出:
array(4) {
[0]=>
array(2) {
["date"]=>
string(16) "2018-02-25 15:12"
["request"]=>
int(11)
}
[1]=>
array(2) {
["date"]=>
string(16) "2018-02-25 15:13"
["request"]=>
int(5)
}
[2]=>
array(2) {
["date"]=>
string(16) "2018-02-25 15:14"
["request"]=>
int(0)
}
[3]=>
array(2) {
["date"]=>
string(16) "2018-02-25 15:15"
["request"]=>
int(2)
}
}
可以做不同的事情,比如只保留第一个,或者添加每个请求(它们在第一个数组中都是零)。不过机制应该是一样的。