Как проверить данные массива, которые совпадают со случайными символами в php? - PullRequest
0 голосов
/ 29 апреля 2018

У меня есть массив, как показано ниже:

$fruits = array("apple","orange","papaya","grape")

У меня есть переменная, как показано ниже:

$content = "apple";

Мне нужно отфильтровать какое-то условие, например: если эта переменная соответствует хотя бы одному из элементов массива, что-то сделать. Переменная $content представляет собой набор случайных символов, который фактически является одним из них, доступных в данных массива, как показано ниже:

$content = "eaplp"; // it's a dynamically random char from the actual word "apple`

то, что я сделал, было похоже на следующее:

$countcontent = count($content);

for($a=0;$a==count($fruits);$a++){

      $countarr = count($fruits[$a]);

      if($content == $fruits[$a] && $countcontent == $countarr){
          echo "we got".$fruits[$a];
      }

}

Я пытался посчитать, сколько букв были в этих словосочетаниях и как if...else..., когда общее слово в строке совпадает с общим словом в одном из данных массива, но есть ли что-то, что мы могли бы сделать, кроме этого?

Ответы [ 9 ]

0 голосов
/ 09 мая 2018

При использовании случайного токена для поиска значения в вашем массиве возникает проблема с ложными срабатываниями . Это может дать неверные результаты в зависимости от варианта использования.

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

Решение для длины строки

Очень легко реализовать.

Ложные срабатывания : Почти каждая строка такой же длины, как apple и grape, будет соответствовать.

Пример :

$matching = array_filter($fruits, function ($fruit) use ($content) {
    return strlen($content) == strlen($fruit);
});
if (count($matching)) {
    // do your stuff...
}

Регулярное выражение решение

Он сравнивает длину строки и ограниченным образом содержит символы. Он умеренный для реализации и имеет хорошую производительность при работе с большими данными.

Ложные срабатывания : контент типа abc будет соответствовать bac, но также bbb.

Пример

$matching = preg_grep(
     '#['.preg_quote($content).']{'.strlen($content).'}#',
      $fruits
);
if (count($matching)) {
    // do your stuff...
}

Буквенно-цифровой сортировочный раствор

Самый точный, но медленный подход к производительности с использованием PHP.

Ложные срабатывания : содержимое, подобное abc, будет соответствовать bac или cab.

Пример

$normalizer = function ($value) {
    $tokens = str_split($value);
    sort($tokens);
    return implode($tokens);
};
$matching = array_filter($fruits, function ($fruit) use ($content, $normalizer) {
    return ($normalizer($fruit) == $normalizer($content));
});
if (count($matching)) {
    // do your stuff...
}
0 голосов
/ 10 мая 2018

if (in_array ("apple", $ fruits)) { верное утверждение } Еще { еще заявление }

0 голосов
/ 09 мая 2018

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

$fruits = array("apple","orange","papaya","grape");
$content = "eaplp";

    foreach ($fruits as $key => $fruit) {
        $fruit_array = str_split($fruit); // split the string into array
        $content_array = str_split($content); // split the content into array

        // check if there's no difference between the 2 new array
        if ( sizeof(array_diff($content_array, $fruit_array)) === 0 ) {
            echo "we found the fruit at key: " . $key;
            return;
        }
    }
0 голосов
/ 09 мая 2018

Как насчет использования только нативных функций PHP.

$index = array_search(count_chars($content), array_map('count_chars', $fruits));

Если $index не равно нулю, вы получите позицию $content внутри $fruits.

P.S. Имейте в виду, что count_chars может быть не самым быстрым подходом к этой проблеме.

0 голосов
/ 09 мая 2018

Мне нравится ответ t.m.adams, но у меня также есть решение этой проблемы:

array_search_random (строка $ needle, массив $ haystack [, bool $ strictcase = FALSE]);

Описание: поиск строки в элементах массива независимо от положения символов в элементе.

  • игла: символы, которые вы ищите как нить
  • стог сена: массив, который вы хотите найти
  • строгий регистр: если для ИСТИНЫ установлено значение TRUE, то будет соответствовать «настроению» и «гибели», но не «настроению» и «гибели», если установлено значение «ЛОЖЬ» (= по умолчанию), оно будет соответствовать всем этим.

Функция:

 function array_search_random($needle, $haystack, $strictcase=false){

  if($strictcase === false){
   $needle = strtolower($needle);     
  }

  $needle = str_split($needle);
            sort($needle);
  $needle = implode($needle);

  foreach($haystack as $straw){

   if($strictcase === false){
    $straw = strtolower($straw);     
   }

   $straw = str_split($straw);
            sort($straw);
   $straw = implode($straw);

   if($straw == $needle){
    return true;
   }

  }

  return false;

 }
0 голосов
/ 09 мая 2018

Вот чистый подход. Возвращает расшифрованное значение рано, если найдено, в противном случае возвращает ноль. Только возвращает точное совпадение.

function sortStringAlphabetically($stringToSort)
{
    $splitString = str_split($stringToSort);
    sort($splitString);

    return implode($splitString);
}

function getValueFromRandomised(array $dataToSearch = [], $dataToFind)
{
    $sortedDataToFind = sortStringAlphabetically($dataToFind);

    foreach ($dataToSearch as $value) {
        if (sortStringAlphabetically($value) === $sortedDataToFind) {
            return $value;
        }
    }

    return null;
}

$fruits = ['apple','orange','papaya','grape'];
$content = 'eaplp';

$dataExists = getValueFromRandomised($fruits, $content);

var_dump($dataExists);
// string(5) "apple" 

Пример не найден:

$content = 'eaplpo';
var_dump($dataExists);
// NULL

Тогда вы можете использовать его (например) так:

echo !empty($dataExists) ? $dataExists . ' was found' : 'No match found';

ПРИМЕЧАНИЕ. В этом регистре учитывается регистр, то есть он не найдет «Apple» из «eaplp». Эту проблему можно решить, выполнив strtolower() для условий цикла vars.

0 голосов
/ 07 мая 2018

Это также будет работать, но немного по-другому.

Я разбил строки на массивы и отсортировал их в соответствии друг с другом.
Затем я использую array_slice, чтобы сопоставить только количество символов в $content, если они совпадают, это совпадение.
Это означает, что это будет соответствовать «свободным» способом с «яблочным соком» или «яблочным творогом».

Не уверен, что это нужно, но подумал, что это может быть кому-то полезно.

$fruits = array("apple","orange","papaya","grape","apple juice", "applecurd");
$content = "eaplp";
$content = str_split($content);
$count = count($content);

Foreach($fruits as $fruit){
    $arr_fruit = str_split($fruit);
    // sort $content to match order of $arr_fruit
    $SortCont = array_merge(array_intersect($arr_fruit, $content), array_diff($content, $arr_fruit));
    // if the first n characters match call it a match
    If(array_slice($SortCont, 0, $count) == array_slice($arr_fruit, 0, $count)){
        Echo "match: " . $fruit ."\n";
    }
}

вывод:

match: apple
match: apple juice
match: applecurd

https://3v4l.org/hHvp3
Это также сравнимо по скорости с ответом t.m.adams. Иногда быстрее, иногда медленнее, но обратите внимание, как этот код может найти несколько ответов. https://3v4l.org/IbuuD

0 голосов
/ 03 мая 2018

Мы можем проверить, содержит ли массив какое-либо значение с помощью in_array. Таким образом, вы можете проверить, содержит ли ваш массив $fruits строку "apple" с,

in_array("apple", $fruits)

, который возвращает логическое значение.

Если порядок букв случайный, мы можем отсортировать строку в алфавитном порядке с помощью этой функции:

function sorted($s) {
    $a = str_split($s);
    sort($a);
    return implode($a);
}  

Затем сопоставьте эту функцию с вашим массивом и проверьте, содержит ли она отсортированную строку.

$fruits = array("apple","orange","papaya","grape");
$content = "eaplp";
$inarr = in_array(sorted($content), array_map("sorted", $fruits));

var_dump($inarr);
//bool(true)

Другой вариант - array_search. Преимущество использования array_search состоит в том, что он возвращает позицию элемента (если он найден в массиве, иначе false).

$pos = array_search(sorted($content), array_map("sorted", $fruits));

echo ($pos !== false) ? "$fruits[$pos] found." : "not found.";  
//apple found.
0 голосов
/ 30 апреля 2018

Как насчет циклического прохождения массива и использования флага, чтобы увидеть, соответствует ли он?

$flag = false;

foreach($fruits as $fruit){
    if($fruit == $content){
        $flag = true;
    }
}

if($flag == true){
    //do something
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...