Reputation: 22490
Trying to create a search for users where I have an array like this:
Original Array:
array(2) {
[1]=>
array(1) {
["string"]=>"One two three, Blue, Green, Yellow"
}
[2]=>
array(1) {
["string"]=>"One two four, Blue, Green, Yellow"
}
}
Now how can I do a regex with the words from input field which could be "one two blue four" and then change the given array order (in this case to):
array(2) {
[1]=>
array(1) {
["string"]=>"One two four, Blue, Green, Yellow"
}
[2]=>
array(1) {
["string"]=>"One two three, Blue, Green, Yellow"
}
}
Cause Original Array [2] has got more matches. Also I would like the order to change already if a user writes "one two blue f"
I've tried with array_diff but I need some opposite array_diff function (showing all the matches) and probably a regex to make it work with single letters.
Any advices would be much appreciated!
Upvotes: 0
Views: 66
Reputation: 5899
I would explode the search term and check each word with stripos()
or substr_count()
against the string in the array. The one that has more occurrences goes up if it has less it goes down. You can use usort()
for this.
Your sorter could look like this one:
class OccurrenceSorter {
private $searchTerm;
public function sort(array $arr, $searchTermStr) {
$this->searchTerm = preg_split('/\s+/', $searchTermStr);
usort($arr, array($this, 'doSort'));
return $arr;
}
private function doSort($a, $b) {
$aScore = $this->getScore($a['string']);
$bScore = $this->getScore($b['string']);
if($aScore == $bScore)
return 0;
return ($aScore < $bScore)?1:-1;
}
private function getScore($str) {
$score = 0;
$strLower = strtolower($str);
foreach($this->searchTerm as $st) {
// substr_count() or strpos() depending on the wished behavior
$score += substr_count($strLower, strtolower($st));
}
return $score;
}
}
$arr = array(
array('string' => 'One two three, Blue, Green, Yellow'),
array('string' => 'One two four, Blue, Green, Yellow')
);
$searchTerm = 'one two blue four';
$rs = new OccurrenceSorter();
$sortedArr = $rs->sort($arr, $searchTerm);
var_dump($sortedArr);
Please note that I used substr_count()
in the example abouth. So the string
two four, four, four, Blue, Blue, Green, Yellow
Is "higher" than the following string (altough this string covers more different search terms):
One two four, Blue, Green, Yellow
In total the first string has 6 matches (two, four, four, four, Blue, Blue) and the second one has 4 matches (One, two, four, Blue). If this is not the wished behavior use strpos()
. You can then use substr_count()
if strpos()
of a
and b
are the same to get one higher ranked than the other.
Upvotes: 1