生成具有不规则步长的范围。优化
PHP 是否有针对不规则步长范围的现有功能,是否有通用的解决方案来提供此功能,或者如何优化以下功能?
第一个函数是我关心的函数。第二个函数是一个现实世界的用例,它生成一个数组来填充输出 HTML 选择下拉列表的函数的值。
<?php
function range_multistep($min, $max, Array $steps, $jmp = 10) {
$steps = array_unique($steps);
sort($steps, SORT_NUMERIC);
$bigstep = ($jmp > 0) ? $jmp : $jmp * -1;
$e = ($min > 0) ? floor(log($min, $bigstep)) : 0;
for (; ; $e++) {
foreach ($steps as $step) {
$jump = pow($bigstep, $e);
$num = $step * $jump;
if ($num > $max) {
break 2;
} elseif ($num >= $min) {
$arr[] = $num;
}
}
}
$arr = array_unique($arr);
sort($arr, SORT_NUMERIC);
return $arr;
}
function prices() {
$price_steps = range_multistep(50, 100000, array(5, 10, 25));
$prev_step = 0;
foreach ($price_steps as $price) {
$price_str = '$' . $prev_step . ' - $' . ($price - 1);
$price_arr[] = $price_str;
$prev_step = $price;
}
$price_arr[] = '$' . end($price_steps) . "+";
return $price_arr;
}
print_r(prices());
上一个结果:
Array
(
[0] => $0 - $49
[1] => $50 - $99
[2] => $100 - $249
[3] => $250 - $499
[4] => $500 - $999
[5] => $1000 - $2499
[6] => $2500 - $4999
[7] => $5000 - $9999
[8] => $10000 - $24999
[9] => $25000 - $49999
[10] => $50000 - $99999
[11] => $100000+
)
Does PHP have existing functionality for irregular step ranges, is there a common solution to provide this functionality, or how can the following function be optimized?
The first function is the function I am concerned about. The second function is a real world use case that generates an array to populate values for a function that outputs a select dropdown for HTML.
<?php
function range_multistep($min, $max, Array $steps, $jmp = 10) {
$steps = array_unique($steps);
sort($steps, SORT_NUMERIC);
$bigstep = ($jmp > 0) ? $jmp : $jmp * -1;
$e = ($min > 0) ? floor(log($min, $bigstep)) : 0;
for (; ; $e++) {
foreach ($steps as $step) {
$jump = pow($bigstep, $e);
$num = $step * $jump;
if ($num > $max) {
break 2;
} elseif ($num >= $min) {
$arr[] = $num;
}
}
}
$arr = array_unique($arr);
sort($arr, SORT_NUMERIC);
return $arr;
}
function prices() {
$price_steps = range_multistep(50, 100000, array(5, 10, 25));
$prev_step = 0;
foreach ($price_steps as $price) {
$price_str = '
The result of the previous:
Array
(
[0] => $0 - $49
[1] => $50 - $99
[2] => $100 - $249
[3] => $250 - $499
[4] => $500 - $999
[5] => $1000 - $2499
[6] => $2500 - $4999
[7] => $5000 - $9999
[8] => $10000 - $24999
[9] => $25000 - $49999
[10] => $50000 - $99999
[11] => $100000+
)
. $prev_step . ' -
The result of the previous:
. ($price - 1);
$price_arr[] = $price_str;
$prev_step = $price;
}
$price_arr[] = '
The result of the previous:
. end($price_steps) . "+";
return $price_arr;
}
print_r(prices());
The result of the previous:
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
重复的加法最好用乘法来代替,重复的乘法最好用幂次来代替——你已经这么做了。
我认为这里没有任何需要改进的地方,假设您在面对
$jmp = 1
或$min >= $max
行为不良时不需要“防弹”行为输入。Repeated addition is best replaced by multiplication, and repeated multiplication is best replaced by raising to powers -- which you've done.
I see nothing here that requires improvement assuming you don't need "bulletproof" behavior in the face of
$jmp = 1
or$min >= $max
badly-behaved inputs.for
循环中的$e
增量器更像是一个while(1)
无限循环。因此,不要在
pow()
中滥用增量器,而是通过每次迭代乘以一次来自行执行pow
。调用pow()
的开销可能相当大,因此您自己进行pow
计算可以更好地将乘法分配到每次迭代中。编辑:以下是函数的变体,它在迭代中分配
pow()
计算。此外,它执行更正确的变量初始化(例如,未设置返回值),如果$min
和$max
交换并更正,则发出通知,使用abs
而不是您的三元,如果为log()
指定了无效值,则会引发异常,重命名一些变量并将$num
添加到返回值中,如下所示首先键以节省array_unique
最后的操作:如果你觉得实验性,也可以将两个循环(
for
+foreach
)变成一个,但代码的可读性并没有好处来自它:我认为如果你注意不要重复使用变量(如函数参数)并让它们更好地读取名称,改进就会自然而然地出现。
The
$e
incrementor in thefor
loop is more of awhile(1)
endless loop.So instead misusing the incrementor in
pow()
, do thepow
on your own by just multiplying once per iteration. Callingpow()
can be pretty expensive, so doing thepow
calculation your own would better distribute the multiplication onto each iteration.Edit: The following is a variant of your function that distributes the
pow()
calculation over the iteration. Additionally it does more proper variable initialisation (the return value was not set for example), gives notice if$min
and$max
are swapped and corrects that, usesabs
instead of your ternary, throws an exception if an invalid value was given forlog()
, renamed some variables and add$num
to the return value as key first to spare thearray_unique
operation at the end:In case you feel experimental, it's also possible to turn the two loops (
for
+foreach
) into one, but the readability of the code does not benefit from it:I think if you take care to not re-use variables (like the function parameter) and give them better to read names, improvement comes on it's own.