I have an array like below:
$fruits = array("apple","orange","papaya","grape")
I have a variable like below:
$content = "apple";
I need to filter some condition like: if this variable matches at least one of the array elements, do something. The variable, $content
, is a bunch of random characters that is actually one of these available in the array data like below:
$content = "eaplp"; // it's a dynamically random char from the actual word "apple`
what have I done was like the below:
$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]; } }
I tried to count how many letters these phrases had and do like if...else...
when the total word in string matches with the total word on one of array data, but is there something that we could do other than that?
8 Answers
Answers 1
You can check if an array contains some value with in_array
. So you can check if your $fruits
array contains the string "apple"
with,
in_array("apple", $fruits)
which returns a boolean.
If the order of the letters is random, you can sort the string alphabetically with this function:
function sorted($s) { $a = str_split($s); sort($a); return implode("", $a); }
Then map this function to your array and check if it contains the sorted string.
$fruits = array("apple","orange","papaya","grape"); $content = "eaplp"; $inarr = in_array(sorted($content), array_map("sorted", $fruits)); var_dump($inarr); //bool(true)
Another option is array_search
. The benefit from using array_search
is that it returns the position of the item if it's found in the array, else false
. An example:
$pos = array_search(sorted($content), array_map("sorted", $fruits)); echo ($pos !== false) ? "$fruits[$pos] found." : "not found."; //apple found.
Answers 2
This will also work but in a slightly different manner.
I split the strings to arrays and sort them to match eachoter.
Then I use array_slice to only match the number of characters in $content
, if they match it's a match.
This means this will match in a "loose" way to with "apple juice" or "apple curd".
Not sure this is wanted but figured it could be useful for someone.
$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"; } }
output:
match: apple match: apple juice match: applecurd
https://3v4l.org/hHvp3
It is also comparable in speed with t.m.adams answer. Sometimes faster sometimes slower, but note how this code can find multiple answers. https://3v4l.org/IbuuD
Answers 3
Here's a clean approach. Returns unscrambled value early if found, otherwise returns null. Only returns an exact match.
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"
Not found example:
$content = 'eaplpo'; var_dump($dataExists); // NULL
Then you can use it (eg) like this:
echo !empty($dataExists) ? $dataExists . ' was found' : 'No match found';
NOTE: This is case sensitive, meaning it wont find "Apple" from "eaplp". That can be resolved by doing strtolower()
on the loop's condition vars.
Answers 4
How about looping through the array, and using a flag to see if it matches?
$flag = false; foreach($fruits as $fruit){ if($fruit == $content){ $flag = true; } } if($flag == true){ //do something }
Answers 5
I like t.m.adams answer but I also have a solution for this issue:
array_search_random(string $needle, array $haystack [, bool $strictcase = FALSE ]);
Description: Searches a string in array elements regardless of the position of the characters in the element.
- needle: the caracters you are looking for as a string
- haystack: the array you want to search
- strictcase: if set to TRUE needle 'mood' will match 'mood' and 'doom' but not 'Mood' and 'Doom', if set to FALSE (=default) it will match all of these.
Function:
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; }
Answers 6
I think this is the simplest way to answer that question. some of the algorithm above seems to be "overkill".
$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; } }
Answers 7
What about using only native PHP functions.
$index = array_search(count_chars($content), array_map('count_chars', $fruits));
If $index
is not null you will get the position of $content
inside $fruits
.
P.S. Be aware that count_chars
might not be the fastest approach to that problem.
Answers 8
With a random token to search for a value in your array, you have a problem with false positives. That can give misleading results depending on the use case.
On search cases, for example wrong typed words, I would implement a filter solution which produces a matching array. One could sort the results by calculating the levenshtein distance to fetch the most likely result, if necessary.
String length solution
Very easy to implement.
False positives: Nearly every string with the same length like apple
and grape
would match.
Example:
$matching = array_filter($fruits, function ($fruit) use ($content) { return strlen($content) == strlen($fruit); }); if (count($matching)) { // do your stuff... }
Regular expression solution
It compares string length and in a limited way containing characters. It is moderate to implement and has a good performance on big data cases.
False positives: A content like abc
would match bac
but also bbb
.
Example:
$matching = preg_grep( '#['.preg_quote($content).']{'.strlen($content).'}#', $fruits ); if (count($matching)) { // do your stuff... }
Alphanumeric sorting solution
Most accurate but also a slow approach concerning performance using PHP.
False positives: A content like abc
would match on bac
or cab
.
Example:
$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 comments:
Post a Comment