0

I Have the following Array and I would like to sort it based on the $term = "geo" in relation only to [result_title] ?

Array
(
    [0] => Array
        (
            [result_title] => Agathoklis Georgiou
            [result_subtext] => Active Employee
        )

    [1] => Array
        (
            [result_title] => Frixos Georgiou
            [result_subtext] => Active Employee
        )

    [2] => Array
        (
            [result_title] => George Ellinas
            [result_subtext] => Active Employee
        )

    [3] => Array
        (
            [result_title] => Georgi Georgiev
            [result_subtext] => Active Employee
        )

    [4] => Array
        (
            [result_title] => Charalambos Georgiou
            [result_subtext] => Former Employee
        )

    [5] => Array
        (
            [result_title] => Georgia Kantouna
            [result_subtext] => Former Employee
        )
)

The desired result should be:

Array
(
    [0] => Array
        (
            [result_title] => George Ellinas
            [result_subtext] => Active Employee

        )

    [1] => Array
        (
            [result_title] => Georgi Georgiev
            [result_subtext] => Active Employee


        )

    [2] => Array
        (
            [result_title] => Georgia Kantouna
            [result_subtext] => Former Employee
        )

    [3] => Array
        (
            [result_title] => Agathoklis Georgiou
            [result_subtext] => Active Employee
        )

    [4] => Array
        (
            [result_title] => Charalambos Georgiou
            [result_subtext] => Former Employee
        )

    [5] => Array
        (
            [result_title] => Frixos Georgiou
            [result_subtext] => Active Employee
        )
)

I have tried various methods such as:

usort($data, function($a, $b) use ($term) {
    $x = strpos($a["result_title"], $term) === false;
    $y = strpos($b["result_title"], $term) === false;
    if ($x && !$y) return 1;
    if ($y && !$x) return -1;

    // use this if you want to sort alphabetically after the keyword sort:
    return strcmp($a["result_title"], $b["result_title"]);

    // or if you only want to sort by whether or not the keyword was found:
    return 0;
});

and

usort($data, function ($a, $b) use ($term) {
    similar_text($term, $a["result_title"], $percentA);
    similar_text($term, $b["result_title"], $percentB);

    return $percentA === $percentB ? 0 : ($percentA > $percentB ? -1 : 1);
});

and

usort($data, function ($a, $b) use ($term) {
    $levA = levenshtein($term, $a["result_title"]);
    $levB = levenshtein($term, $b["result_title"]);

    return $levA === $levB ? 0 : ($levA > $levB ? 1 : -1);
});

and

usort($data, function($a, $b){ return $a["result_title"] - $b["result_title"]; }); 

and many more without any proper result. Or maybe I cannot understand the method to achieve my result?

I have also checked: php sorting an array based on a string and How to sort an array by similarity in relation to an inputted word. but the answers are giving me the result I'm looking for.

8
  • 1
    can you provide your source array as PHP code? Commented Nov 10, 2018 at 22:16
  • @MarcinOrlowski you mean how the array is formed at first? Commented Nov 10, 2018 at 22:23
  • it does not matter where it comes from. Make it in valid PHP array so I can try w/o wasting time to convert this data into code myself :) Commented Nov 10, 2018 at 22:26
  • Array ( [0] => Array ( [result_title] => Agathoklis Georgiou [result_subtext] => Active Employee ) [1] => Array ( [result_title] => Frixos Georgiou [result_subtext] => Active Employee ) [2] => Array ( [result_title] => George Ellinas [result_subtext] => Active Employee ) [3] => Array ( [result_title] => Georgi Georgiev [result_subtext] => Active Employee ) [4] => Array ( [result_title] => Charalambos Georgiou [result_subtext] => Former Employee ) ) Commented Nov 10, 2018 at 22:28
  • @MarcinOrlowski I hope this is what you meant :S Commented Nov 10, 2018 at 22:29

1 Answer 1

1

Here's a function that I think will do what you want. I've presumed you want to find the value of $term at the beginning of a word. This code extracts any keyword in the title which includes $term and then sorts based on whether the keyword was found, followed by the ordering of the keyword, or if they are both the same, on the title.

$term = 'geo';
usort($data, function ($a, $b) use ($term) {
    // find the term in first entry
    $t1 = preg_match("/^.*?\b($term\w*)\b.*\$/i", $a['result_title'], $matches) ? $matches[1] : '';
    // find the term in second entry
    $t2 = preg_match("/^.*?\b($term\w*)\b.*\$/i", $b['result_title'], $matches) ? $matches[1] : '';
    // check if the terms were found
    if ($t1 == '' && $t2 != '') return 1;
    if ($t1 != '' && $t2 == '') return -1;
    // found in both - if not the same, just sort on the keyword
    if ($t1 != $t2) return strcmp($t1, $t2);
    // found the same keyword, sort on the whole title
    return strcmp($a['result_title'], $b['result_title']);
});

Since the output is long (it is what you asked for) I've omitted it but I've made a demo on 3v4l.org.

Sign up to request clarification or add additional context in comments.

7 Comments

I dont know how to thank you enough. I've been trying so much the past 48 hours. Thank you!
Would it make a difference if I set the term string to lower? There is some confusions for example
@jQuerybeast I'm not sure what you mean by "set the term string to lower"?
@jQuerybeast I've made an edit to the answer to allow for the term being the whole word.
@jQuerybeast the way the code works it won't sort that way because 'LIA' < 'Lia'. If you want it to be case-insensitive change the strcmp to strcasecmp
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.