PHP 减去数组值

发布于 2025-01-01 10:48:27 字数 561 浏览 1 评论 0原文

我有一个包含键和值的数组。每个值都是一个整数。我有另一个具有相同键的数组。如何减去匹配键的所有值?此外,可能有一些键不会出现在第二个数组中,但两个数组的长度相同。如果数组 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)
*/

我没有在此处添加键位于一个数组中而不是另一个数组中的情况。

I have an array with keys and values. Each value is an integer. I have an other array with the same keys. How can I subtract all of the values for the matching keys? Also there might be keys that do not occur in the second array but both arrays have the same length. If there is a key in array 2 that is not present in array 1 its value should be unchanged. If there is a key in the first array that is not in the second it should be thrown away. How do I do it? Is there any built-in function for this?

If I would write a script it would be some kind of for loop like this:

$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)
*/

I did not add the occasion here a key is in one array and not in the other.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

岁月无声 2025-01-08 10:48:27

如果您愿意的话,可以避免使用数组函数的 foreach 。

提供给 array_map< 的闭包下面的 em>docs 将从每个相应的 $arr2 中减去每个 $arr1 值。不幸的是,当使用多个输入数组时,array_map 不会保留您的密钥,因此我们使用 array_combinedocs 将减去的结果合并回带有原始键的数组:

$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 中很好的老式循环。当然,您应该始终选择更具可读性/语义的选项;如果这样的微观优化会让代码在六个月后变得更难以理解,那么它们就是不合理的。

You could avoid the foreach using array functions if you were so inclined.

The closure provided to array_mapdocs below will subtract each $arr1 value from each corresponding $arr2. Unfortunately array_map won't preserve your keys when using more than one input array, so we use array_combinedocs to merge the subtracted results back into an array with the original keys:

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

UPDATE

I was interested in how the array functions approach compared to a simple foreach, so I benchmarked both using Xdebug. Here's the test code:

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

As it turns out, using the foreach loop is an order of magnitude faster than accomplishing the same task using array functions. As you can see from the below KCachegrind callee image, the array function method required nearly 80% of the processing time in the above code, while the foreach function required less than 5%.

enter image description here

The lesson here: sometimes the more semantic array functions (surprisingly?) can be inferior performance-wise to a good old fashioned loop in PHP. Of course, you should always choose the option that is more readable/semantic; micro-optimizations like this aren't justified if they make the code more difficult to understand six months down the road.

ぇ气 2025-01-08 10:48:27
foreach ($arr2 as $key => $value) {
    if(array_key_exists($key, $arr1) && array_key_exists($key, $arr2))
        $ret[$key] = $arr2[$key] - $arr1[$key];
}
foreach ($arr2 as $key => $value) {
    if(array_key_exists($key, $arr1) && array_key_exists($key, $arr2))
        $ret[$key] = $arr2[$key] - $arr1[$key];
}
行雁书 2025-01-08 10:48:27

PHP 不提供向量化数学运算。我会坚持使用您当前使用循环的方法。

首先,我将获取每个数组的数组键集。 (请参阅 array_keys 函数)。然后,将它们相交。现在您将拥有每个数组通用的键。 (看一下 array_intersect 函数)。最后,迭代。这是一种可读且简单的方法。

最后,您可以查看一个库,例如 Math_Vector: http://pear.php.net/包/Math_Vector

PHP does not offer vectorized mathematical operations. I would stick with your current approach of using a loop.

First, I would get the set of array keys for each array. (See the array_keys function). Then, intersect them. Now you will have the keys common to each array. (Take a look at the array_intersect function). Finally, iterate. It's a readable and simple approach.

Lastly, you could take a look at a library, such as Math_Vector: http://pear.php.net/package/Math_Vector

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文