[英]PHP consecutive subtraction two arrays
我有 2 个这样的数组
a = Array([101] => 5,[109] =>100,[220] => 50,[231] => 45,[245] => 90)
b = Array(['PRO'] => 12,['LOG'] => 15,['DEV'] => 100)
我想连续减去 2 个数组并得到这样的结果
c = Array([101] => 0,[109] => 0, [220] => 28, [231] => 45, [245] => 90)
解释:我假设使用 foreach 来获取 a 和 b 的值
1st: 5-12=0(move 7 to next time) <=> c[101] => 0;
2nd: 100-7 = 93 (7 at 1st)
3rd : 93-15 = 78
4th: 78-100 = 0 (move 22 to 5th time) <=> c[109] => 0
5th: 50-22 = 28 <=> c[220] => 28
但我不知道如何用PHP表达
以下应该工作:
$rest = 0;
foreach ($a as &$value) {
if ($value < $rest) {
$rest -= $value;
$value = 0;
continue;
} else {
$value -= $rest;
$rest = 0;
}
while ($value > 0 && key($b) !== null) {
if ($value < current($b)) {
$rest = current($b) - $value;
$value = 0;
} else {
$value = $value - current($b);
$rest = 0;
}
next($b);
}
}
基本上,这在第一个数组和每个循环中循环:
可以在3v4l上找到一个工作示例。
我会尝试重新表述您的要求,因为在我理解您的需求之前,我不得不阅读您的问题大约 10 次。
您想通过按照关联元素出现的顺序消耗$b
中的值来减少$a
的值(使用减法)。 当在一个价值$b
足够大的减少值$a
零或更低时,你要设置的$a
值为零,并携带在剩余价值(差)到下一个值的减法$a
。 这个携带价值必须被$a
的一个或多个价值消耗,直到它被耗尽。 当一个携带值耗尽时,应该使用$b
下一个出现的值来减少$a
的当前值。
12
( $b[PRO]
) 用于将5
( $a[101]
) 减少到0
( new $a[101]
) 然后7
成为进位值, $a
的下一个值将成为新的焦点。100
( $a[109]
) 先减7
( carried
) 变成93
( new $a[109
) 。93
( new [109]
) 然后再次减少15
( $b[LOG]
) 变成78
( new [109]
)。78
( new [109]
然后,通过再次降低100
( $b[DEV]
的值地板到0
,使得一个新的进行值22
,并移动聚焦到$a[220]
50
( $a[220]
) 减去22
( carried
) 变成28
( new $a[220]
)。$b
中没有更多值可以减少$a
值。$a[231]
和$a[245]
保持不变,因为没有剩余的值可以减去。 我的片段使用教科书算术术语: minuend - suprahend = difference
。
$difference
是携带的东西。
array_shift()
是合适的,因为它在访问时消耗$b
的值。
代码:(演示)
$a = [
101 => 5,
109 => 100,
220 => 50,
231 => 45,
245 => 90
];
$b = [
'PRO' => 12,
'LOG' => 15,
'DEV' => 100
];
$difference = 0;
foreach ($a as &$minuend) {
while ($minuend && ($b || $difference < 0)) {
$suprahend = $difference < 0 ? -$difference : array_shift($b);
$difference = $minuend - $suprahend;
$minuend = max(0, $difference);
}
}
var_export($a);
输出:
array (
101 => 0,
109 => 0,
220 => 28,
231 => 45,
245 => 90,
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.