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.

3
  • 1
    php.net/manual/en/function.usort.php Commented Feb 8, 2016 at 14:49
  • Possible duplicate of Sort an Array by keys based on another Array? Commented Feb 8, 2016 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. Commented Feb 8, 2016 at 14:57

2 Answers 2

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);
Sign up to request clarification or add additional context in comments.

4 Comments

This is brilliant! Best one so far. Short and simple. Will keep an eye open for even better solutions.
Does it finally suit your needs?
I'm quite happy with this solution for now!
Great ! I would be glad if you accept the answer, if you think it's ok ;-)
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);

1 Comment

This one makes sense too, but a bit more cumbersome than the $order_to_sort_by_reversed suggestion.

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.