【问题标题】:Searching PHP array quickly快速搜索 PHP 数组
【发布时间】:2017-04-12 20:52:41
【问题描述】:

我有一个包含大约 3500 个数组项的数组,格式如下。我有两个变化的动态变量,我需要根据已经知道的 price_slot 和国家/地区搜索数组以找出行 price_value。

我目前有以下内容,但这需要的时间太长。无论如何我可以加快访问速度吗?

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
        )

有没有更快的方法来解决这个问题?

谢谢!

【问题讨论】:

  • 如何填充数组?如果您总是检查price_slotcountry,则可以在构建数组时使用该组合作为数组索引,而不是使用数字索引。然后你可以简单地使用isset() 来检查它是否存在,并返回它的price_value
  • 看起来应该在数据库中
  • 我通过 csv @rickdenhaan 填充数组,所以很遗憾无法动态检查!
  • 你每次都动态填充数组吗?这很可能是它很慢的原因
  • @EmilioGort,不,不是。

标签: php arrays search foreach


【解决方案1】:

我还在想其他方法,但这样更快:

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

那么你需要访问:

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

您可以像这样在$result 中获取price_value

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

【讨论】:

    【解决方案2】:

    一个可能的解决方案是索引您的数组(与您的数据库相同)。通过创建一个包含您正在搜索的索引的多维数组,您将能够立即返回正确的条目。当您必须获得超过 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 次完整迭代。检索超过 1 个元素时提高性能。 O(1) 的速度。

    【讨论】:

      【解决方案3】:

      为什么不在加载数据时创建数组的键控版本?

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

      之后,可以在恒定时间内按价格段和国家/地区查找条目:

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

      当然,这仅在您进行多次查找时才有用。

      注意:只有在给定价格段和国家/地区没有唯一定义记录的情况下,您才需要复制中间数组级别。

      【讨论】:

        猜你喜欢
        • 2014-11-29
        • 2015-05-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-23
        • 1970-01-01
        • 1970-01-01
        • 2021-09-18
        相关资源
        最近更新 更多