2010-10-27 51 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]; 
相關問題