0

I have an array of indexes that I want to sort my other array:

$order = [7, 2, 1, 4];

$array = [
   1 => "O",
   2 => "T"
   4 => "F"
   7 => "S"
]

How can I order the $array based on $order array, so that the output is..

$array = [
   7 => "S",
   2 => "T"
   1 => "O",
   4 => "F"
]

As far as I read, something other than for loop is much preferred

senty
  • 10,294
  • 23
  • 99
  • 215

1 Answers1

2

You could make use of uksort and array_search:

uksort($array, static function (int $key1, int $key2) use ($order): int {
    return array_search($key1, $order, true) <=> array_search($key2, $order, true);
});

The idea is to sort the array by the positions of its items' keys within the $order array:

  • uksort is a sorting function that allows sorting based on array keys (here 1, 2, 4 and 7),
  • array_search($key1, $order, true) gives you $key1's position within $order,
  • array_search($key2, $order, true) gives you $key2's position within $order,
  • <=> (known as the spaceship operator) compares these values, so that the sorting puts lower values (aka lower positions within $order) first.

Demo

Note: performance could be bad if your array is big, as array_search will be run several times on the same keys. If that's an issue, what you can do is grab all keys' positions within $order first, then sort based on them.

Jeto
  • 13,447
  • 2
  • 22
  • 39
  • Please employ the spaceship operator Jeto. I am using this page to close others. If you can add a bit more explanation, that would be helpful too. – mickmackusa Feb 26 '21 at 15:19
  • @mickmackusa Done. Spaceship operator should be exactly equivalent to `-` here (and I'm wondering if it's got any performance overhead, though probably not), but you're right that it's more common/understandable in the context of a sorting callback. – Jeto Feb 26 '21 at 20:29
  • Sorry, I had in my mind that modern php versions would complain about the subtraction -- my mistake. – mickmackusa Feb 27 '21 at 00:43