0

I need to sort a multidimensional array by two values.

For example in the array will be 4 keys.

Array(
    Array
    (
        [0] => 4B642D022980E5EBAA7CF4B6E1CC93769921CB42
        [1] => downloading
        [2] => Title
        [3] => 60
    )
    Array
    (
        [0] => 4B642D022980E5EBAA7CF4B6E1CC93769921CB42
        [1] => downloading
        [2] => Title
        [3] => 30
    )
    Array
    (
        [0] => 4B642D022980E5EBAA7CF4B6E1CC93769921CB42
        [1] => paused
        [2] => Title
        [3] => 30
    )
    Array
    (
        [0] => 4B642D022980E5EBAA7CF4B6E1CC93769921CB42
        [1] => completed
        [2] => Title
        [3] => 100
    )
)

Is there a way I can sort the array so that it would sort the arrays with key completed first, then downloading second, then paused third and then also sort the arrays containing downloading and paused from 100 down to 0 by the 3 key?

Desired output would be

Array(
    Array
    (
        [0] => 4B642D022980E5EBAA7CF4B6E1CC93769921CB42
        [1] => completed
        [2] => Title
        [3] => 100
    )
    Array
    (
        [0] => 4B642D022980E5EBAA7CF4B6E1CC93769921CB42
        [1] => downloading
        [2] => Title
        [3] => 60
    )
    Array
    (
        [0] => 4B642D022980E5EBAA7CF4B6E1CC93769921CB42
        [1] => downloading
        [2] => Title
        [3] => 30
    )
    Array
    (
        [0] => 4B642D022980E5EBAA7CF4B6E1CC93769921CB42
        [1] => paused
        [2] => Title
        [3] => 30
    )
)
3
  • 2
    This question is a little short on information. Can you share what you have tried, and what problems have you run into? Commented Jan 23, 2015 at 21:32
  • 1
    Take a look at php.net/manual/en/function.usort.php Commented Jan 23, 2015 at 21:32
  • I know how to sort basic arrays but I wouldn't know where to start on a more complex array like this unfortunately. Commented Jan 23, 2015 at 21:33

3 Answers 3

1

uksort is what you need.

It is a sort that lets you define you own callback function.

This callback function is then used by uksort to reorder the array.

You need to write a function that will sort an array based on two criterias.

The first one is the alphabetical order of the field at indice 1 of your array (which contains the words completed, downloading, ...) and in case of tie you would then use the field at indice 3 of your array and sort in decreasing order.

Finally, you will need to pass the function you created as a parameter to uksort.

Hope it helps ! :)

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

Comments

1

You need to reformat your array and use array_multisort. It will also make thinks more readable:

<?php $ar = Array(
    Array(
        "id" => "4B642D022980E5EBAA7CF4B6E1CC93769921CB42",
        "status" => "completed",
        "title" => "Title",
        "rank" => "100",
    ),
    Array
    (
        "id" => "4B642D022980E5EBAA7CF4B6E1CC93769921CB42",
        "status" => "downloading",
        "title" => "Title",
        "rank" => "60",
    ),
    Array
    (
        "id" => "4B642D022980E5EBAA7CF4B6E1CC93769921CB42",
        "status" => "downloading",
        "title" => "Title",
        "rank" => "30",
    ),
    Array
    (
        "id" => "4B642D022980E5EBAA7CF4B6E1CC93769921CB42",
        "status" => "paused",
        "title" => "Title",
        "rank" => "30",
    ),
);
var_dump($ar);
foreach ($ar as $key => $row) {
    $status[$key] = $row['status'];
    $rank[$key] = $row['rank'];
}

array_multisort($status, SORT_ASC, $rank, SORT_DESC, $ar);
var_dump($ar);

Comments

0
    $array = [
        [
            '4B642D022980E5EBAA7CF4B6E1CC93769921CB42',
            'downloading',
            'Title',
            '60',
        ],
        [
            '4B642D022980E5EBAA7CF4B6E1CC93769921CB42',
            'downloading',
            'Title',
            '30',
        ],
        [
            '4B642D022980E5EBAA7CF4B6E1CC93769921CB42',
            'paused',
            'Title',
            '30',
        ],
        [
            '4B642D022980E5EBAA7CF4B6E1CC93769921CB42',
            'completed',
            'Title',
            '100',
        ]
    ];


    usort($array, function($a, $b) {
        if ($a[1] == $b[1]) {
            if ($a[3] == $b[3]) {
                return 0;
            }

            return ($a[3] > $b[3]) ? -1 : 1;
        }

        $status = ['completed', 'downloading', 'paused'];

        foreach ($status as $st) {
            if ($a[1] == $st)
                return -1;
            if ($b[1] == $st)
                return 1;
        }

        return 0;
    });


    var_dump($array);

Comments

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.