2017-04-12 230 views
2

我有一個陣列裏面有大約3500個數組項,格式如下。我有兩個動態變量發生了變化,我需要根據已知的price_slot和country來搜索數組以找出行price_value。快速搜索PHP數組

我目前已經得到了下面,但這是花了太長時間。無論如何,我可以加快訪問速度嗎?

PHP函數

$country = US; 
$priceSlot = 3; 
$priceValue = getPriceValue($priceSlot, $country); 


function getPriceValue($priceSlot, $country) { 
    // Search in array for price 
    foreach ($array as $arrayItem) { 
     if ($arrayItem['price_slot'] == $priceSlot && $arrayItem['country'] == $country) { 
      return $arrayItem['price_value']; 
     } 
    } 
    return null; 
} 

陣列的片段

Array 
(
    [0] => Array 
     (
      [price_slot] => 1 
      [base_price] => Get in Touch 
      [country] => US 
      [price_multiplier] => 
      [price_value] => Get in Touch 
     ) 

    [1] => Array 
     (
      [price_slot] => 2 
      [base_price] => 9000 
      [country] => US 
      [price_multiplier] => 1.3 
      [price_value] => 11700 
     ) 

    [2] => Array 
     (
      [price_slot] => 3 
      [base_price] => 12000 
      [country] => US 
      [price_multiplier] => 1.3 
      [price_value] => 15600 
     ) 

    [3] => Array 
     (
      [price_slot] => 4 
      [base_price] => 15000 
      [country] => US 
      [price_multiplier] => 1.3 
      [price_value] => 19500 
     ) 

    [4] => Array 
     (
      [price_slot] => 5 
      [base_price] => 4000 
      [country] => US 
      [price_multiplier] => 1.3 
      [price_value] => 5200 
     ) 

    [5] => Array 
     (
      [price_slot] => 6 
      [base_price] => 1600 
      [country] => US 
      [price_multiplier] => 1.3 
      [price_value] => 2080 
     ) 

有沒有更快的方法來解決這個問題?

謝謝!

+0

你如何填充你的數組?如果您總是檢查'price_slot'和'country',那麼在構建數組時可能會將該組合用作數組索引,而不是使用數字索引。然後你可以簡單地使用'isset()'來檢查它是否存在,並返回它的'price_value'。 – rickdenhaan

+0

看起來應該是這樣的DB – nogad

+0

我通過csv @rickdenhaan填充數組,所以不能動態檢查那個不幸的! – DIM3NSION

回答

3

我還在試圖想另闢蹊徑,但這是更快:

$result = array_filter($array, function($v) use($priceSlot, $country) { 
            return ($v['price_slot'] == $priceSlot && 
              $v['country'] == $country); 
           }); 

那麼你就需要訪問:

echo current($result)['price_value']; 

你可以得到price_value$result這樣:

array_filter($array, function($v) use(&$result, $priceSlot, $country) { 
         $result = ($v['price_slot'] == $priceSlot && 
            $v['country'] == $country) ? 
            $v['price_value'] : null; 
        }); 
0

一個可能的解決方案是索引你的數組(同樣的事情你的數據庫呢)。通過創建一個包含正在搜索的索引的多維數組,您將能夠立即返回正確的條目。如果您必須獲得超過1個條目的價格值(因爲索引成本爲1次完整迭代),您肯定會看到性能提升。請注意,此技術特別適用於索引對象,索引數組值會花費更多內存。

用於索引陣列的例子:

$index = array(); 

foreach ($array as $entry) { 
    $country = $index['country']; 
    $priceSl = $index['price_slot']; 

    if (!isset($index[$country][$pricelSl])) { 
     $index[$country][$pricelSl] = array(); 
    } 

    $index[$country][$pricelSl][] = $entry; 
} 

下一步是抓住從索引條目:

function getPriceValue($country, $priceSlot) use ($index) { 
    if (isset($index[$country][$pricelSl])) { 
     // Return the first entry, we could have more theoretically. 
     return reset($index[$country][$pricelSl]); 
    } 

    return null; 
} 

TL; DR:1所需的完全迭代。檢索多個元素時提高性能。 O(1)的速度。

0

爲什麼不在您加載數據時創建陣列的鍵控版本?

foreach ($array as $arrayItem) { 
    $hash[$arrayItem['price_slot'] . $arrayItem['country']][] = $arrayItem; 
} 

之後,仰視按價格插槽和國家的入境可在固定時間內完成:

function getPriceValue($priceSlot, $country) { 
    return $hash[$priceSlot . $country][0]['price_value']; 
} 

當然,如果你正在做一個以上的查找,這是唯一有用的。

注意:中間數組級別僅適用於您希望複製給定價格槽和國家/地區不唯一定義記錄的情況。