1

I have an associative array something like this:

$return['data']

Array (
[0] => Array
    (
        [id] => 19957
        [yt_id] => 19957-OPEN
        [name] => 19957-OPEN
        [score] => N/A
    )

[1] => Array
    (
        [id] => 19965
        [yt_id] => 19965-OPEN
        [name] => 19965-OPEN
        [score] => N/A
    )

[2] => Array
    (
        [id] => 20034
        [yt_id] => UCGbcYB89XesffWVJKPUpA
        [name] => 1994firebug
        [score] => 458.43
    )

[3] => Array
    (
        [id] => 20036
        [yt_id] => UCGbcfgXexlIirWVJKPUpA
        [name] => 1994firebug
        [score] => 344.69
    ) );

I'm sorting this array on the basis of score in ascending and descending order.

So now of the values in the array for score are 'N/A'.

So when sorting in ascending the the score with 'N/A' values shows at last. And when descending it shows up in the beginning.

Now what I want to do is whether ascending or descending the array should be sorted accordingly based on the score values but when score values are 'n/a' I want all those 'N/A' values to show at the end of the array at all times whether its ascending or descending.

Here is my code.

if($sort_by == "score"){
    if($sort_direction == "asc") {
       uasort($return['data'], function($a, $b) use ($sort_by) { return strnatcmp($a[$sort_by], $b[$sort_by]);});                       

    }   else {
       uasort($return['data'], function($a, $b) use ($sort_by) { return strnatcmp($b[$sort_by], $a[$sort_by]); });                              
    }
    $return['data'] = array_slice($return['data'], $start, $length);  
}

I hope my question is clear and if someone can help with an easy and efficient solution.

Edit:- I thought of doing this - check if the values of score in the array are 'N/A' unset them from their position and move them to the last. Although it is still not working I'm getting an error "Illegal offset type in unset". I don't know what I'm doing wrong there.

I'm doing this once the whole array is sorted in the if else statements.

    foreach ($return['data'] as $key) {
                    if($key['score'] == 'N/A'){
                    $item = $key;
                    unset($key);
                    array_push($return['data'], $item); 
                }
}

Even though if it works my application has hundreds in some cases thousands of records to sort in an array. So sorting this way has already become very slow. So I'm sure using any more loops or something like what I'm trying to do will make it even more slow. Which is not feasible in my case. So does anyone have a better solution to this?

Edit: I've changed the code a bit and its no longer giving me an illegal offset error. But still it's not working as I expected it to. Not removing all the N/A values and putting them in the end.

1 Answer 1

1

To simplify it:

usort($data, function (array $a, array $b) {
    if ($a['score'] == $b['score']) {
        return 0;
    }
    if ($a['score'] == 'N/A') {
        return -1;
    }
    if ($b['score'] == 'N/A') {
        return 1;
    }
    return $a['score'] - $b['score'];
});

If both values are equal ("N/A" or anything else), the result is 0, else if a is "N/A" (and the other one is not, as proven in the previous step), then a is greater, vice versa for b, else do a general numeric comparison.

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

1 Comment

that works perfect. thanks for the amazing solution.

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.