forthrin February 2016

Sorting an array in order defined by other array

Does PHP have the capability to sort an array of items (A) in an order that is defined by another array (B)? Eg. the item that comes first in B decides which item should come first when sorting A.

$order_to_sort_by = array("Gold", "Silver", "Bronze");
$items_to_sort = array("Bronze", "Silver", "Bronze", "Gold", "Bronze", "Silver");

some_sort_function($items_to_sort, $order_to_sort_by);

Result:

Gold
Silver
Silver
Bronze
Bronze
Bronze

EDIT: The duplicate that was suggested seems to use keys of another array to determine which keys in the array should be used for sorting. Somewhat unclear, but I don't think it's a duplicate.

Answers


Mat February 2016

You could try something like this

$order_to_sort_by = array("Gold", "Silver", "Bronze");
$items_to_sort = array("Bronze", "Silver", "Bronze", "Gold", "Bronze", "Silver");

$order_to_sort_by_reversed = array_flip($order_to_sort_by);
$sortByArray = function($a, $b) use ($order_to_sort_by_reversed)
{
    return $order_to_sort_by_reversed[$a] - $order_to_sort_by_reversed[$b];
};
usort($items_to_sort, $sortByArray);

var_dump($items_to_sort);


Alex Belyaev February 2016

You can use usort function to define how to compare elements of array. Example:

$order_to_sort_by = array("Gold", "Silver", "Bronze");
$items_to_sort = array("Bronze", "Silver", "Bronze", "Gold", "Bronze", "Silver");

usort(
    // What to sort. Input array will be changed!
    $items_to_sort, 

    // Lets define comparing function inplace
    // ...just cause we can use anonymous functions: 
    function($a, $b) use ($order_to_sort_by) {
        // Find position of two comparing elements
        // ...in our ranking array to find what element
        // ...is 'greater' than another
        $a_pos = array_search($a, $order_to_sort_by);
        $b_pos = array_search($b, $order_to_sort_by);

        // 0 means that items will not be swapped
        // 1 for moving $b up
        // -1 for moving $b down
        if ($a_pos == $b_pos) {
            return 0;
        } else if ($a_pos > $b_pos) {
            return 1;
        } else {
            return -1;
        }

        // I hope in php7 it would be able
        // to use `spaceship` operator in this case
        // instead of these if`s:
        //     return $a <=> $b
    }
);

var_dump($items_to_sort);

Post Status

Asked in February 2016
Viewed 1,080 times
Voted 14
Answered 2 times

Search




Leave an answer