我有一个包含键和值的数组。每个值都是一个整数。我有另一个具有相同键的数组。如何减去匹配键的所有值?也可能有一些键没有出现在第二个数组中,但两个数组的长度相同。如果数组 2 中有一个键在数组 1 中不存在,则其值应保持不变。如果第一个数组中有一个键不在第二个数组中,则应将其丢弃。我该怎么做?是否有任何内置函数?
如果我要写一个脚本,它会像这样的某种 for 循环:
$arr1 = array('a' => 1, 'b' => 3, 'c' => 10);
$arr2 = array('a' => 2, 'b' => 1, 'c' => 5);
$ret = array();
foreach ($arr1 as $key => $value) {
$ret[$key] = $arr2[$key] - $arr1[$key];
}
print_r($ret);
/*
should be: array('a' => 1, 'b' => -2, 'c' => -5)
*/
我没有在这里添加一个键在一个数组中而不在另一个数组中的场合。
最佳答案
如果您愿意,可以避免使用数组函数的 foreach。
提供给 array_map
docs 的闭包下面将从每个相应的 $arr2
中减去每个 $arr1
值。不幸的是,当使用多个输入数组时,array_map
不会保留您的键,因此我们使用 array_combine
docs将减去的结果合并回具有原始键的数组:
$arr1 = array('a' => 1, 'b' => 3, 'c' => 10);
$arr2 = array('a' => 2, 'b' => 1, 'c' => 5);
$subtracted = array_map(function ($x, $y) { return $y-$x; } , $arr1, $arr2);
$result = array_combine(array_keys($arr1), $subtracted);
var_dump($result);
更新
我对数组函数与简单的 foreach 相比如何处理很感兴趣,因此我使用 Xdebug 对两者进行了基准测试。这是测试代码:
$arr1 = array('a' => 1, 'b' => 3, 'c' => 10);
$arr2 = array('a' => 2, 'b' => 1, 'c' => 5);
function arrayFunc($arr1, $arr2) {
$subtracted = array_map(function ($x, $y) { return $y-$x; } , $arr1, $arr2);
$result = array_combine(array_keys($arr1), $subtracted);
}
function foreachFunc($arr1, $arr2) {
$ret = array();
foreach ($arr1 as $key => $value) {
$ret[$key] = $arr2[$key] - $arr1[$key];
}
}
for ($i=0;$i<10000;$i++) { arrayFunc($arr1, $arr2); }
for ($i=0;$i<10000;$i++) { foreachFunc($arr1, $arr2); }
事实证明,使用 foreach
循环比使用数组函数完成相同任务快一个数量级。从下面的 KCachegrind 调用者图像可以看出,数组函数方法需要上述代码中近 80% 的处理时间,而 foreach 函数只需要不到 5%。
这里的教训:有时更多语义数组函数(令人惊讶?)在性能方面可能不如 PHP 中的老式循环。当然,您应该始终选择更具可读性/语义的选项;如果像这样的微优化使代码在六个月后更难以理解,那么这种微优化是不合理的。
关于PHP 减去数组值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9118150/