2010-10-27 18 views
12

挑选最近的值进行排序:从一个数组反映我都取决于项目的数量,反映的回扣比例数组范围

$rebates = array(
    1 => 0, 
    3 => 10, 
    5 => 25, 
    10 => 35) 

这意味着一个或两个项目,你不退;对于3件以上的商品,你得到10%,5件商品20%,10+ 35%等等。

是否有优雅,单行获得任意数量物品的正确折扣百分比,比如7

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

我打算把接受的答案奖励给200,但显然我必须等24小时才能做到这一点。问题解决了。

+3

你知道这是没有意义的要求单行当你不指定最大行的长度;) – Gordon 2010-10-27 11:41:07

+0

键不是一种模式?因此,我们不能做一个功能 – nerkn 2010-10-27 11:41:18

+0

@戈登:在代码之前的高尔夫。 – BoltClock 2010-10-27 11:42:46

回答

16

这里有另外一个,又不是总之很短。

$percent = $rebates[max(array_intersect(array_keys($rebates),range(0,$items)))]; 

的想法基本上是要获取的是地方0$items之间的最高键(max)。

+0

+1整齐实用 – 2010-10-27 13:18:03

+0

我接受这一个,因为它非破坏性地工作,是最短的方法,并且不需要全局/封闭。谢谢! – 2010-10-27 15:12:58

+0

+1相对较短且功能强大 – Thariama 2010-10-28 06:23:23

1

没有这样的核心功能!

1

尽我所能到目前为止管理:

$testValue = 7; 
array_walk($rebates, function($value, $key, &$test) { if ($key > $test[0]) unset($test[1][$key]); } array($testValue,&$rebates)); 

用途引用传递的讨厌的小怪癖,并剥去$回扣数组,其中的关键是数字超过$测试值更大的任何条目...不幸的是,它仍然留下低键入口,所以需要array_pop()来获得正确的值。请注意,它会主动减少原始$ rebates数组中的条目。

也许有人可以在此基础上放弃阵列中较低的条目。

目前没有5.3.3可用,所以没有使用匿名函数进行测试,但在使用标准回调函数时工作(尽可能多地工作)。

编辑

建立在我以前的一个内胆,增加第二线(所以也许应该不算):

$testValue = 7; 
array_walk($rebates, function($value, $key, &$test) { if ($key > $test[0]) unset($test[1][$key]); } array($testValue,&$rebates)); 
array_walk(array_reverse($rebates,true), function($value, $key, &$test) { if ($key < $test[0]) unset($test[1][$key]); } array(array_pop(array_keys($rebates)),&$rebates)); 

现在仅造成包含单个的$回扣数组元素,它是原始$ rebates数组中最高的断点键,它是一个比$ testValue更低的键。

+0

+1有趣的方法! – 2010-10-27 12:34:51

2

这可能在不更改折扣数组的情况下起作用。

但数组必须以另一种方式为这个构建工作

$rebates = array(
    3 => 0,  //Every number below this will get this rebate 
    5 => 10, 
    10 => 25, 
    1000 => 35); //Arbitrary large numer to catch all 

$count = $_REQUEST["count"]; 

$rv = $rebates[array_shift(array_filter(array_keys($rebates), function ($v) {global $count; return $v > $count;}))]; 

echo $rv; 

工作的测试用例,只是改变URL计算

http://empirium.dnet.nu/arraytest.php?count=5
http://empirium.dnet.nu/arraytest.php?count=10

+0

非常好,谢谢。我接受@ salathe的方法,因为它稍微短一点,并且没有全局/闭包,但是这也可以很好地工作。 – 2010-10-27 15:14:11

+0

因为,他的解决方案更优雅:-) – 2010-10-27 19:01:38

5

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

$items = NUM_OF_ITEMS; 
$rabate = 0; 
foreach ($rabates as $rItems => $rRabate) { 
    if ($rItems > $items) break; 
    $rabate = $rRabate; 
} 

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

好吧,我知道,你不想用简单的循环解决方案。但这又如何:

while (!isset($rabates[$items])) { 
    --$items; 
} 
$rabate = $rabates[$items]; 

还是挺简单的,但稍微短一点。我们可以做得更短吗?

for (; !isset($rabates[$items]); --$items); 
$rabate = $rabates[$items]; 

我们已经接近一条线。所以让我们做一点作弊:

for (; !isset($rabates[$items]) || 0 > $rabate = $rabates[$items]; --$items); 

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

for ($i = $items; !isset($rabates[$i]) || 0 > $rabate = $rabates[$i]; --$i); 

这是一次一个字符少,我们保持$items

虽然我认为最后两个版本已经太过于黑客了。这一个更好地坚持,因为它是短期和理解:

for ($i = $items; !isset($rabates[$i]); --$i); 
$rabate = $rabates[$i]; 
相关问题