Sort array by its keys using a pre-defined array of custom key orders
Asked Answered
K

5

9
$a = array(0=>'a',1=>'b',2=>'c', 3=>'d');

I want to change the order to be 3,2,0,1

$a = array(3=>'d',2=>'c',0=>'a', 1=>'b');
Kisner answered 1/2, 2010 at 8:3 Comment(2)
You mean something like this array_reverse?Cutting
Please check my answer with uksort() below.Phosphoric
P
23

If you want to change the order programmatically, have a look at the various array sorting functions in PHP, especially

  • uasort()— Sort an array with a user-defined comparison function and maintain index association
  • uksort()— Sort an array by keys using a user-defined comparison function
  • usort()— Sort an array by values using a user-defined comparison function

Based on Yannicks example below, you could do it this way:

$a = array(0 => 'a', 1 => 'b', 2 => 'c', 3 => 'd');
$b = array(3, 2, 0, 1); // rule indicating new key order
$c = array();
foreach($b as $index) {
    $c[$index] = $a[$index];
}
print_r($c);

would give

Array([3] => d [2] => c [0] => a [1] => b)

But like I said in the comments, if you do not tell us the rule by which to order the array or be more specific about your need, we cannot help you beyond this.

Probity answered 1/2, 2010 at 8:19 Comment(1)
Check my answer with uasort() below.Phosphoric
U
7

Since arrays in PHP are actually ordered maps, I am unsure if the order of the items is preserved when enumerating.

If you simply want to enumerate them in a specific order:

$a = array(0=>'a',1=>'b',2=>'c', 3=>'d');
$order = array(3, 2, 0, 1);

foreach ($order as $index)
{
  echo "$index => " . $a[$index] . "\n";
}
Udometer answered 1/2, 2010 at 8:24 Comment(2)
Is there another way than iterating?Kisner
What exactly are you trying to do? Because I cannot see another reason why to change the 'order' of the elements in the array apart from enumerating the collection in a certain order.Udometer
B
7
function reorder_array(&$array, $new_order) {
  $inverted = array_flip($new_order);
  uksort($array, function($a, $b) use ($inverted) {
    return $inverted[$a] > $inverted[$b];
  });
}

$a = array(0=>'a',1=>'b',2=>'c', 3=>'d');
reorder_array($a, array(3, 2, 0, 1));

var_dump($a);

Result:

Array ( [3] => d [2] => c [0] => a [1] => b )
Bakery answered 25/12, 2012 at 12:37 Comment(0)
P
1

The easiest way to do it with uksort(), more functional way:

$a = ['a','b','c','d'];
$order = [3, 2, 0, 1];

uksort($a, function($x, $y) use ($order) {
    return array_search($x, $order) > array_search($y, $order);
});

print_r($a); // [3 → d, 2 → c, 0 → a, 1 → b]
Phosphoric answered 1/6, 2016 at 14:1 Comment(0)
D
0

A more general aproach:

$ex_count = count($ex_names_rev_order);
$j = 0;
$ex_good_order = array();
for ($i=($ex_count - 1); $i >= 0 ; $i--) { 

    $ex_good_order[$j] = $ex_names_rev_order[$i];
    $j++;
}
Duggins answered 15/3, 2019 at 17:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.