2

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.

forthrin
  • 2,709
  • 3
  • 28
  • 50
  • 1
    http://php.net/manual/en/function.usort.php – WheatBeak Feb 08 '16 at 14:49
  • Possible duplicate of [Sort an Array by keys based on another Array?](http://stackoverflow.com/questions/348410/sort-an-array-by-keys-based-on-another-array) – CodeGodie Feb 08 '16 at 14:55
  • I saw that article, but didn't quite grasp what he's doing. It seems like something different. I thought about translating the values in A to the key (index) value of the corresponding item in B, then sort, then translate back. I'll never have more than a few hundred items, so performance is not a critical issue. – forthrin Feb 08 '16 at 14:57

2 Answers2

3

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);
Mat
  • 2,134
  • 1
  • 18
  • 21
2

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);
Alex Belyaev
  • 1,417
  • 1
  • 11
  • 15
  • This one makes sense too, but a bit more cumbersome than the `$order_to_sort_by_reversed` suggestion. – forthrin Feb 08 '16 at 15:44