foreach next 操作数组指针移动问题,多个数连加,连除,连减,连乘php版本
2018年10月20日10:39:40
先说结论,foreach 维护的是一套属于自己的数组指针
会在操作数据的时候,分裂一套变量地址,即使你强制使用 & 取地址一样会分裂,不会引用同一套指针
所有在foreach的时候需要主动操作指针的时候,就会出现问题,很容易key超出变量的长度
测试demo
1,测试指针是否同步,会受到数组操作函数的影响
$a = [3,4,5,6,7]; foreach ($array as $k => $v) { p($v); p(next($array)); }
结果是不受影响,如果需要复杂指针操作就需要,自己移动指针,使用以下的方法
while(key($a)!==null){ echo key($a)."=>".current($a)."\n"; next($a); }
对象指针操作参看
https://www.cnblogs.com/zx-admin/p/10430782.html
以下是一个实例
连续 加 减 乘 除
$parameter = [10, 20, 30, 40, 50, 60]; $rr = $parameter; for ($i = 1; $i <= (count($rr) - 1 ); $i++) { p($i); reset($parameter); $data_1 = current($parameter); array_shift($parameter); $data_2 = current($parameter); array_shift($parameter); // if (!empty($data_2)) { $res = bcdiv($data_1, $data_2, 2); array_unshift($parameter, $res); p($parameter); }
封装过的方法
2019年1月2日12:07:01 经过修改过的方法
//多个参数 bc系列 加 减 乘 除 可扩展 if (!function_exists('multiple_parameters_bc')) { /* * add 加 * sub 减 * mul 乘 * div 除 */ function multiple_parameters_bc($type = 'add', $accuracy = 2, ...$parameter) { // pp($parameter); //bc 对小数点位数不是四舍五入,先高精度计算最后对小数点位数四舍五入 // $calculation_accuracy 计算时保持的小数点精度 返回值保留的精度$accuracy $calculation_accuracy = 10; if (count($parameter) < 2) { throw new \Exception('参数少于2个'); } //防止数组操作导致循环次数异常 $temp = $parameter; for ($i = 1; $i <= (count($temp) - 1 ); $i++) { // p($i); //保证指针一直指向数组第一个元素 reset($parameter); //获取第一个元素 $data_1 = current($parameter); array_shift($parameter); //获取第二个元素 $data_2 = current($parameter); array_shift($parameter); if ($type == 'add') { $res = bcadd($data_1, $data_2, $calculation_accuracy); } elseif ($type == 'sub') { $res = bcsub($data_1, $data_2, $calculation_accuracy); } elseif ($type == 'mul') { // if ((int) $data_2 == 0) { // throw new \Exception('被乘元素不能为0'); // } $res = bcmul($data_1, $data_2, $calculation_accuracy); } elseif ($type == 'div') { if ((int) $data_2 == 0) { throw new \Exception('被除元素不能为0'); } $res = bcdiv($data_1, $data_2, $calculation_accuracy); } else { throw new \Exception('计算类型不识别'); } //计算结果再次压入队首,循环继续使用 array_unshift($parameter, $res); } //加减不需要四舍五入,只需要截取小数位精度 ,乘除需要四舍五入 if ($type == 'add') { return number_format($parameter['0'], $accuracy, '.', ''); } elseif ($type == 'sub') { return number_format($parameter['0'], $accuracy, '.', ''); } elseif ($type == 'mul') { return round($parameter['0'], $accuracy); } elseif ($type == 'div') { return round($parameter['0'], $accuracy); } else { throw new \Exception('计算类型不识别'); } } }
经过测试没有什么问题,注意出发的时候,结果溢出,因为是没计算完就四舍五入,如果特殊需要,可以自己优化一下除法
修改版本1
function multiple_parameters_bc(string $type = '+', int $accuracy = 2, ...$parameter) { // pp($parameter); //bc 对小数点位数不是四舍五入,先高精度计算最后对小数点位数四舍五入 // $calculation_accuracy 计算时保持的小数点精度 返回值保留的精度$accuracy $calculation_accuracy = 30; if (count($parameter) < 2) { throw new \Exception('参数少于2个'); } //防止数组操作导致循环次数异常 $temp = $parameter; for ($i = 1; $i <= (count($temp) - 1 ); $i++) { // p($i); //保证指针一直指向数组第一个元素 reset($parameter); //获取第一个元素 $data_1 = current($parameter); array_shift($parameter); //获取第二个元素 $data_2 = current($parameter); array_shift($parameter); if ($type == '+') { $res = bcadd($data_1, $data_2, $calculation_accuracy); } elseif ($type == '-') { $res = bcsub($data_1, $data_2, $calculation_accuracy); } elseif ($type == '*') { // if ((int) $data_2 == 0) { // throw new \Exception('被乘元素不能为0'); // } $res = bcmul($data_1, $data_2, $calculation_accuracy); } elseif ($type == '/') { if ((int) $data_2 == 0) { throw new \Exception('被除元素不能为0'); } $res = bcdiv($data_1, $data_2, $calculation_accuracy); } else { throw new \Exception('计算类型不识别'); } //计算结果再次压入队首,循环继续使用 array_unshift($parameter, $res); } //加减不需要四舍五入,只需要截取小数位精度 ,乘除需要四舍五入 if ($type == '+') { return number_format($parameter['0'], $accuracy, '.', ''); } elseif ($type == '-') { return number_format($parameter['0'], $accuracy, '.', ''); } elseif ($type == '*') { return round($parameter['0'], $accuracy); } elseif ($type == '/') { return round($parameter['0'], $accuracy); } else { throw new \Exception('计算类型不识别'); } }
参考
http://www.phppan.com/2013/04/foreach-exception/
https://blog.csdn.net/asty9000/article/details/82860124
QQ一群 247823727
QQ二群 166427999
博客文件如果不能下载请进群下载
如果公司项目有技术瓶颈问题,请联系↓↓
如果需要定制系统开发服务,请联系↓↓
技术服务QQ: 903464207
QQ二群 166427999
博客文件如果不能下载请进群下载
如果公司项目有技术瓶颈问题,请联系↓↓
如果需要定制系统开发服务,请联系↓↓
技术服务QQ: 903464207