性能:搜索值并返回子数组的键

时间:2013-04-13 16:25:39

标签: php performance

给出如下数组:

$nouns = array(
    "man" => array("men"),
    "octopus" => array("octopi", "octopuses"),
    "ox" => array("oxen")
);

由大约3000个单数 - 复数对组成,如何通过调用array_search_loosely($nouns, "men")来获得最有效的单数(密钥)?

然后我希望收到一个值为“man”的数组。

我尝试了四种不同的方法:

原始(使用函数array_is_assoc,这是一个相当不言自明的,与情况无关)

function array_search_loosely($array, $values, $compare_keys = false) {
  $values = is_array($values) ? $values : array($values);
  foreach($array as $item_key => $item) {
    if (is_array($item)) {
      $return_key = true;
      foreach($values as $value_key => $value) {
        if (!in_array($value, $item)) {
          $return_key = false;
          break;
        }
        elseif($compare_keys === true and array_is_assoc($values)) {
          if (!in_array($value_key, array_keys($item, $value))) {
            $return_key = false;
            break;
          }
        }
      }
      if ($return_key === true) {
        $item_keys[] = $item_key;
      }
    }
    elseif(!is_array($values)) {
      if ($item === $values) {
        $item_keys[] = $item_key;
      }
    }
  }
  return (isset($item_keys))? $item_keys : false;
}

第二种方法

function array_search_loosely($array, $values, $compare_keys = false) {
    $keys = array_keys(array_filter($array, function($item) use ($values, $compare_keys) {
        return (!is_array($item) and $item === $values) or (is_array($item) and each_in_array($item, array_create($values), $compare_keys));
    }));
    return !empty($keys) ? $keys : false;
}

function each_in_array($array, $values, $compare_keys = false) {
    return $compare_keys === false ? count(array_uintersect($values, $array, function($item1, $item2) { return $item1 === $item2 ? 0 : ($item1 > $item2 ? 1 : -1); })) == count($values) : count(array_uintersect_assoc($values, $array, function($item1, $item2) { return $item1 === $item2 ? 0 : ($item1 > $item2 ? 1 : -1); })) == count($values);
}

我选择使用array_uintersect,也允许数组为$items,因为如果我要使用array_intersect,则会为每个数组$item生成通知。此选项允许each_in_array()检查数组$values

此外,第三个可选参数$compare_keys与此情况无关,但在我使用该函数的其他情况下。

第三种和第四种方法是前述的混合物。此时我的原始方法仍然是最快的,但是当我在几百或几千个单词上运行我的功能时,操作仍将花费几十秒。关于如何在这种情况下提高复数的单数性能的任何建议?

3 个答案:

答案 0 :(得分:0)

您当前格式的地图不适合进行查找。你还需要反转它:

$invert = array(
  'men' => 'man',
  'octopi' => 'octopus',
  'octopuses' => 'octopus',
  'oxen' => 'ox',
);

答案 1 :(得分:0)

$search = 'men';
$found  = '';

foreach($nouns AS $noun => $values){
   if(in_array($search, $values){
        echo 'Found what we\'re looking for.';
        $found = $nouns[$noun];
   }

}

print_r($found);

答案 2 :(得分:0)

输出:

output 源:

<!DOCTYPE html>
<html>
    <body>
        <?php
            $nouns = array  (
                                "data" => array("data"),
                                "datum" => array("data"),
                                "man" => array("men"),
                                "octopus" => array("octopi", "octopuses"),
                                "ox" => array("oxen"),
                                "hippopotamus" => array("hippopotami", "hippopotamuses")
                            );

            function find_singular($nouns, $search)
            {
                foreach($nouns as $noun => $values)
                {
                    if(in_array($search, $values))
                    {
                        $found[] = $noun;
                    }
                }
                if(!empty($found))
                {
                    $n = count($found);
                    if($n > 1)
                    {
                        echo "<strong>$search</strong> has $n singular forms: <em>";
                        print_r(implode('</em> and <em>', $found).'</em><br />');
                    }
                    else
                    {
                        echo "<b>$search</b> is the plural of <em>$found[0]</em><br />";
                    }
                }
                else
                {
                    echo "<b>$search</b> was not found.<br />";
                }
            }

            find_singular($nouns, "men");
            find_singular($nouns, "octopi");
            find_singular($nouns, "data");
            find_singular($nouns, "oxen");
            find_singular($nouns, "octopuses");
            find_singular($nouns, "hippopotami");
            find_singular($nouns, "kittens");
        ?>
    </body>
</html>

希望这有帮助!

编辑: 这样做的目的是什么?我猜你正在为网络或应用程序界面创建一个字典应用程序。只要您打算实施搜索功能,我认为您无法避免循环。你是否将整个字典存储在PHP数组中?我假设你是因为XML和mysql查询会花费更多的时间。我唯一的另一个建议是将字典拆分成你可以管理的数组(每个字母可能只有几十个),否则编写一个脚本来从现有字典数组或平面文件中生成这些数组,然后在你的实现中实现AJAX搜索框,类似于谷歌的预测搜索,但不是在键入搜索字符串时显示可能的结果,而是缩小要在后台静默搜索的数组。我有一个脚本,它可以做到这一点,如果这听起来可行,可以挖掘它。基本上,不是搜索整个字典(我已经看过一个超过一千二百万字!)每个关键字,到键入,发送和处理关键字时,循环周期可能会少得多。硬件也让人想起 - 服务器的硬盘,处理器和内存速度将占大多数。我也听说过C ++更适合字典搜索,对于PHP开发人员来说也不是太陌生的选择。

相关问题