В PHP, что быстрый путь состоит в том, чтобы искать массив значения, которые содержат подстроку?

У меня есть массив названий улицы, отсортированных в алфавитном порядке, что я собрался из веб-сервиса. Этот массив существует на стороне сервера.

На стороне клиента пользователь начинает вводить имя улицы, на которой он живет, и Ajax используется для возврата списка самого близкого соответствия к частичному названию улицы, плюс следующие 9 названий улицы в массиве (обновляется список, в то время как он вводит).

Например, если бы пользователь ввел "al", то я ожидал бы, что результаты будут чем-то как следующее:

  • Albany Hwy
  • Долина альбенов
  • Alcaston Rd
  • Alex Wood доктор
  • Alice Rd
  • Allawah Ct
  • Allen Rd
  • Мн Аллоуэй
  • Аллвуд Av
  • Alola St
  • Amanda доктор

Это - моя попытка в нем:

$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;
  }
}

Кто-либо еще знает более быстрый путь?

Пожалуйста, примите во внимание: Я не имею никакого контроля над тем, как этот список получен из базы данных - это от внешнего веб-сервиса.

5
задан Iain Fraser 21 January 2010 в 08:57
поделиться

4 ответа

единственный способ получить быстрее, чем просматривать все строки, будет иметь структуру данных, оптимизированную для такого рода вещи, TRIE . Возможно, у вас может быть не контролирует то, что WebService дает вам, но если вы сможете кэшировать результат на вашем сервере и повторно использовать его для обслуживания многих запросов, затем построение TRIE и использование, которое будет намного быстрее.

4
ответ дан 18 December 2019 в 09:50
поделиться

Не может действительно сказать, если это быстрее, но это моя версия из этого.

$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 => имя улицы и 1 => Расстояние Левенштейна

4
ответ дан 18 December 2019 в 09:50
поделиться

Я думаю, что вы ищете PREG_GREP ()

. Вы можете искать либо для элементов, начиная с входного текста:

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

или для элементов, которые содержат текст в любом месте:

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

Или вы также можете закрепить поиск до конца, но это не выглядит так полезно

4
ответ дан 18 December 2019 в 09:50
поделиться

Используйте preg_grep():

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

Примечание: этот метод, как и ваш, будет выполнять поиск методом грубой силы. Если вы ищете в огромном списке имен (сотни тысяч) или ищете огромное количество раз, то вам может понадобиться что-то получше. Однако для небольших наборов данных это нормально.

5
ответ дан 18 December 2019 в 09:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: