1

I am creating a word search but I want to rank them base on the highest existence of search keyword. I am trying to make a search if array 1 key exists inside array 2 long string and then order the array by total occurrence of array 1 in array 2.

Example input:

$arr = array(array("id" => 1,"title" => "Hello World", "body" => "Hi Jude All this is my content"), 
             array("id" => 2,"title" => "Hello World Boy", "body" => "Hi All this is my content Girl"),
             array("id" => 3,"title" => "Hello Kids", "body" => "Hi All this is my content Kid"),
             array("id" => 4,"title" => "Hello World Jude", "body" => "Hi All this is my content Jude"),
             array("id" => 5,"title" => "Hello World Jude January", "body" => "Hi All this is my content Jan"),
             array("id" => 6,"title" => "Hello World January June Lord", "body" => "Hi All this is my content Jan Jude Lord"));
$str = "Hello world January jude";

Desire output:

Array in order:

Hello World Jude January
Hello World Jude
Hello World January June Lord
Hello World
Hello World Boy
Hello Kids

I wrote a question earlier base on solving problem for Is there any PHP function to solve out array value matches in another array value string? afterward I got solution on that but my main problem now is that it is judging my filter base on case sensitivity if my search keyword is hello world and I have Hello world and hi world because the world on hi world is lowercase as the one at my search keywords it picks the one with the lowercase first before considering the one with the most matches I have tried several things but I could not get it.

Note: I want the Output to be returned the way it is not to return in lowercase format.

This is what I tried using the example input from above:

$arr2 = sort_most_exists_asc($arr, $str);
var_dump($arr2);

function sort_most_exists_asc($array, $str) {
    usort($array, function ($a, $b) use ($str) {
        $aa = count(array_intersect(explode(" ", $str), explode(" ", $a['title'])));
        $bb = count(array_intersect(explode(" ", $str), explode(" ", $b['title'])));
        return $bb - $aa;
    });
    return $array;
}

Worked well if its formatted exactly like that but I don't want it to follow case sensitivity during the array_intersect.

halfer
  • 19,824
  • 17
  • 99
  • 186

2 Answers2

0

Solved working fine here for people who may need further help on something like this https://3v4l.org/tlvbh.

I fixed the issue by using array-uintersect - which can take function as argument for compare. I send it strcasecmp - to avoid the case-sensitivity in the string compare.

This is my new sort function:

function sort_most_exists_asc($array, $str) {
    usort($array, function ($a, $b) use ($str) {
        $aa = count(array_uintersect(explode(" ", $str), explode(" ", $a['title']), 'strcasecmp'));
        $bb = count(array_uintersect(explode(" ", $str), explode(" ", $b['title']), 'strcasecmp'));
        return $bb - $aa;
    });
    return $array;
}
dWinder
  • 11,597
  • 3
  • 24
  • 39
  • 1
    We’re glad you solved your problem, but please add the solution in your answer here. While this may answer the question, it is better to provide the actual information here and not just a link. [Link-only answers are not considered good answers and will probably be deleted](https://stackoverflow.com/help/deleted-answers). – elixenide Apr 18 '19 at 04:29
0

A few tips:

  • if you want to modify by reference (like php's other sort functions), throw a lamba (&) on the incoming function parameter and omit the return line.

  • in the interests of efficiency, don't explode the search string on each iteration -- explode it only once.

  • the spaceship operator is a great way to sort two arrays by length without explicit counting.

Code: (Demo)

function sort_most_needles(&$array, $str) {
    $needles = explode(" ", $str);
    usort($array, function ($a, $b) use ($needles) {
        return array_uintersect($needles, explode(" ", $b['title']), 'strcasecmp')
               <=>
               array_uintersect($needles, explode(" ", $a['title']), 'strcasecmp');
    });
}

sort_most_needles($arr, $str);

var_export($arr);

The equivalent effect with PHP7.4's arrow function syntax: (Demo)

function sort_most_needles(&$array, $str) {
    $needles = explode(" ", $str);
    usort($array,
          fn($a, $b) =>
              array_uintersect($needles, explode(" ", $b['title']), 'strcasecmp')
              <=>
              array_uintersect($needles, explode(" ", $a['title']), 'strcasecmp')
         );
}
mickmackusa
  • 43,625
  • 12
  • 83
  • 136