从反射范围的数组中选取最接近的值

Pek*_*ica 12 php arrays

我有一个反映折扣百分比的数组,具体取决于订购的商品数量:

$rebates = array(
   1 => 0,
   3 => 10,
   5 => 25,
  10 => 35)
Run Code Online (Sandbox Code Playgroud)

意思是对于一件或两件物品,你没有得到回扣; 对于3个以上的项目,您获得10%,5个以上的项目,20%,10 + 35%等等.

对于任意数量的物品,是否有一种优雅的单线方式来获得正确的回扣百分比7

显然,这可以通过一个简单的循环来解决:这不是我想要的.我很感兴趣是否有一个我不知道的核心数组或其他功能可以更优雅地做到这一点.

我要把接受的答案奖励给200分,但显然,我要等24小时,直到我能做到.问题解决了.

sal*_*the 16

这是另一个,也不是短暂的.

$percent = $rebates[max(array_intersect(array_keys($rebates),range(0,$items)))];
Run Code Online (Sandbox Code Playgroud)

这个想法基本上是获得最高的密钥(max这是介于两者之间)0$items.


Nik*_*kiC 5

我认为上述单行解决方案并不优雅或可读.那么为什么不使用乍一看才真正被人理解的东西呢?

$items = NUM_OF_ITEMS;
$rabate = 0;
foreach ($rabates as $rItems => $rRabate) {
    if ($rItems > $items) break;
    $rabate = $rRabate;
}
Run Code Online (Sandbox Code Playgroud)

这显然需要一个排序数组,但至少在你的例子中给出了这个;)

好的,我知道,你不希望解决方案采用简单的循环.但是这个怎么样:

while (!isset($rabates[$items])) {
    --$items;
}
$rabate = $rabates[$items];
Run Code Online (Sandbox Code Playgroud)

仍然很简单,但有点短.我们能做得更短吗?

for (; !isset($rabates[$items]); --$items);
$rabate = $rabates[$items];
Run Code Online (Sandbox Code Playgroud)

我们已经接近一条线了.让我们做一点作弊:

for (; !isset($rabates[$items]) || 0 > $rabate = $rabates[$items]; --$items);
Run Code Online (Sandbox Code Playgroud)

这比其他答案中的所有方法都要短.它只有一个缺点:它会改变$items您以后可能仍需要的值.所以我们可以这样做:

for ($i = $items; !isset($rabates[$i]) || 0 > $rabate = $rabates[$i]; --$i);
Run Code Online (Sandbox Code Playgroud)

这又是一个字符,我们保持$items.

虽然我认为最后两个版本已经过于hacky了.更好地坚持这一点,因为它既简短又易懂:

for ($i = $items; !isset($rabates[$i]); --$i);
$rabate = $rabates[$i];
Run Code Online (Sandbox Code Playgroud)