1

I have sample function for searching words from array with specified letters:

public static function getWords($words, $specifed_letters) 
{ 
    $pattern = is_array($specifed_letters) ? '/[' . implode("", 
    $specifed_letters) . ']/u' : '/[' .$specifed_letters. ']/u';
    $result = preg_grep($pattern, $array_words);
    return $result;
}

Example usage:

$words = ["apple", "sample", "app", "тоҷик", "отабек", "баҳодурбек"];
$result = getWords($words, $letters = ['l', 's']);

This example will return words: apple, sample. Because in this words have letters "l" or "s".

How I can search words where have all specifed letters in word?

For example if I add to specifed letters "app" then from words array must be return words: app, apple.

And how search word with only specifed letters. For example I will write word "app" in shuffled variant "pap". And how I can get on result only word "app" without "apple"?

Andreas Hunter
  • 4,504
  • 11
  • 65
  • 125

2 Answers2

1

You could split the word characters to an array and loop them, and split the characters from the specified string to an array.

If one of the word characters occur in the characters from the specified string array, remove the character from both arrays.

Once the loop is done, verify that there are no more characters left in the characters from the specified string array.

$words = ["apple", "sample", "app", "justappgg", "тоҷик", "отабек", "баҳодурбек", "APELCIN", "API", "pap"];
mb_internal_encoding("UTF-8");

foreach ($words as $word) {
    $wordSplit = preg_split('//u', $word, null, PREG_SPLIT_NO_EMPTY);
    $strSplit = preg_split('//u', $str, null, PREG_SPLIT_NO_EMPTY);
    $wordSplit = array_filter($wordSplit, function ($x) use (&$strSplit) {
        if (in_array(strtolower($x), array_map('strtolower', $strSplit), true)) {
            $pos = array_search(strtolower($x), array_map('strtolower', $strSplit), true);
            unset($strSplit[$pos]);
            return false;
        }
        return true;
    });
    if (count($strSplit) === 0) {
        echo "$word contains all letters of $str" . PHP_EOL;
    }
}

Demo

The fourth bird
  • 154,723
  • 16
  • 55
  • 70
  • @Otabek This could be a slight refactoring of the code [`Demo`](https://3v4l.org/E4Jgr). I could also add that with an explanation? – The fourth bird May 24 '18 at 09:20
  • Here I create new question for perform it in [codereview](https://codereview.stackexchange.com/questions/195074/how-to-perform-my-functions-which-can-found-words-with-input-specifed-letters) – Andreas Hunter May 24 '18 at 09:24
0

You can use preg_grep.
If you implode the letters inside [] in the regex pattern it should look for the letter and return the item if found.

$words = ["apple", "sample", "app", "тоҷик", "отабек", "баҳодурбек"];
$letters = ['l', 's'];

$res = preg_grep("/[" . implode("", $letters) . "]/", $words); // pattern = "/[ls]/"
var_dump($res);

https://3v4l.org/UZTYZ

EDIT
But this part of your question: And how search word with only specifed letters. For example I will write word "app" in shuffled variant "pap". And how I can get on result only word "app" without "apple"?
Is the exact opposite of the first part where you wanted a very loose search.
Are you expecting one loose and one exact result array?


You can do the exact match by splitting the strings and sorting the letters (in the array).
Then check if the arrays match each other. If they do, then it's an exact match.

$words = ["apple", "sample", "app", "тоҷик", "отабек", "баҳодурбек"]; 
$find = "pap";

$find = str_split($find);
sort($find);
foreach($words as $word){
    $temp = str_split($word);
    sort($temp);
    if($temp == $find){
        echo "match " . $word . "\n";
    }
}

https://3v4l.org/WbTUK

Andreas
  • 23,610
  • 6
  • 30
  • 62
  • Can be it realised with preg_grep for arrays? – Andreas Hunter May 23 '18 at 09:25
  • I don't think so since preg_grep is regex. Regex is loose searching especially if you don't know what order the letters are supposed to be – Andreas May 23 '18 at 09:30
  • Ok. Then with your example how to get `apple` when input is `pap`? Because in `apple` also have one `a` and two `p` letters. – Andreas Hunter May 23 '18 at 09:34
  • You can sort the two arrays with multisort and only compare the number of characters in found with array_slice. https://3v4l.org/4Xqg8 – Andreas May 23 '18 at 09:57
  • I now test your last example for `ple` but not found words. On result must be returned words: `apple` and `sample` because that have letters `ple` – Andreas Hunter May 23 '18 at 10:05