在PHP中,在数组中搜索包含子字符串的值的快速方法是什么?

时间:2010-01-21 08:57:59

标签: php ajax string search arrays

我从网络服务中收集了一系列按字母顺序排序的街道名称。该数组存在于服务器端。

在客户端,用户开始输入他所居住的街道的名称,AJAX用于返回与部分街道名称最接近的匹配的列表,以及阵列中的下9个街道名称(列表)在他打字时更新。

例如,如果用户键入“al”,我希望结果如下:

  • Albany Hwy
  • Albens Vale
  • Alcaston Rd
  • Alex Wood Dr
  • Alice Rd
  • Allawah Ct
  • Allen Rd
  • Alloway Pl
  • Allwood Av
  • Alola St
  • Amanda Dr

这是我的尝试:

$matches = array();
for($i = 0; $i < count($streetNames); $i++)
{
  if( (stripos($streetNames, $input) === 0 && count($matches) == 0) || count($matches) < 10 ){
   $matches[] = $streetNames[$i];
  } else {
   break;
  }
}

有没有其他人知道更快的方式?

请注意:我无法控制如何从数据库中获取此列表 - 它来自外部Web服务。

4 个答案:

答案 0 :(得分:5)

使用preg_grep()

$matches = preg_grep('/al/', $streetNames);

注意:像你这样的方法将是一个强力搜索。如果你正在搜索一个巨大的名单(数十万)或搜索很多次,那么你可能需要更好的东西。对于小数据集,这很好。

答案 1 :(得分:4)

我认为你要找的是preg_grep()

您可以搜索以输入文本开头的元素:

$result = preg_grep('/^$input/', $streetNames);

或包含任何地方文字的元素:

$result = preg_grep('/$input/', $streetNames);

或者你也可以将搜索锚定到最后,但看起来不那么有用

答案 2 :(得分:4)

获得比查看所有字符串更快的唯一方法是为这种事物优化数据结构,trie。您可能无法控制Web服务为您提供的内容,但如果您可以将结果缓存在服务器上并重复使用它来处理许多请求,那么构建一个trie并使用它会更快。

答案 3 :(得分:4)

无法确定它是否更快,但这是我的版本。

$input = 'al';
$matches = array_filter($streetNames, create_function('$v','return (stripos($v,'.$input.') !== false ? true : false);'));
$weight = array_map(create_function('$v','return array($v,levenshtein('.$input.',$v));'),$matches);
uasort($weight, create_function('$a,$b', 'if ($a[1] == $b[1]) {return 0;} return ($a[1] < $b[1]) ? -1 : 1;'));
$weight = array_slice($weight, 0, 10);

这会创建一个加权的匹配列表。它们根据输入字符串和街道名称之间的距离进行排序。 0表示真正的匹配。

结果数组看起来像这样

array (
  0 => 
  array (
    0 => 'Alola St',
    1 => 7,
  ),
  1 => 
  array (
    0 => 'Allen Rd',
    1 => 7,
  )
)

其中0 =&gt;街道名称和1 =&gt; levenshtein距离