Reputation: 30821
Suppose I have an array that I want to sort, and the order is not something computable, but rather, given by another array which lists the keys in the desired order:
$ordering_array = [
'c',
'a',
'k',
'e',
];
As an added complication, not all of these keys might be present in my array to sort:
$given_array = [
'a' => 'value',
'c' => 'value',
'e' => 'value',
];
What is the cleanest / quickest way to achieve this?
My method is:
$new_array = array_fill_keys($ordering_array, NULL);
foreach ($given_array as $key => $value) {
$new_array[$key] = $value;
}
$new_array = array_filter($new_array);
Is there a better way?
Upvotes: 0
Views: 117
Reputation: 7485
Simple and explicit:
<?php
$ordering_array = [
'c',
'a',
'k',
'e',
];
$given_array = [
'a' => 'valuea',
'c' => 'valuec',
'e' => 'valuee',
];
foreach($ordering_array as $K)
if(array_key_exists($K, $given_array))
$ordered[$K] = $given_array[$K];
var_export($ordered);
Output:
array (
'c' => 'valuec',
'a' => 'valuea',
'e' => 'valuee',
)
You might be able to shave off a byte or two with isset($given_array[$K])
if the data allows.
Upvotes: 0
Reputation: 1335
try using uksort,
<?php
$ordering_array = [
'c',
'a',
'k',
'e',
];
$given_array = [
'a' => 'value-a',
'c' => 'value-c',
'e' => 'value-e',
];
uksort($given_array , function ($a, $b) use ($ordering_array) {
$pos_a = array_search($a,$ordering_array);
$pos_b = array_search($b,$ordering_array);
return $pos_a - $pos_b;
});
var_dump($given_array );
Upvotes: 0
Reputation: 8297
you can try this
$filteredKeys = array_intersect_key(array_flip($ordering_array), $given_array);
$outputArray = array_merge($filteredKeys, $given_array);
Upvotes: 1
Reputation: 1572
Use array_merge()
or array_replace
at the place of foreach, both worked
Try this:
$ordering_array = ['c', 'a', 'k', 'e'];
$given_array = ['a' => 'value', 'c' => 'value', 'e' => 'value'];
$new_array = array_fill_keys($ordering_array, NULL);
$new_array = array_merge($new_array, $given_array);
OR
$new_array = array_replace($new_array, $given_array);
$new_array = array_filter($new_array);
Upvotes: 1
Reputation: 3257
This is a oneliner that solves it:
$ordering_array = ['c', 'a', 'k', 'e'];
$given_array = ['a' => 'value', 'c' => 'value', 'e' => 'value'];
$outputArray = array_merge(array_intersect_key(array_flip($ordering_array), $given_array), $given_array);
print_r($outputArray);
@rkj was close, but this is how it's done
Test here: http://sandbox.onlinephpfunctions.com/code/95b30f6e402b1afdb18867471888ff8ba38867de
Upvotes: 1
Reputation: 57131
You can replace the foreach
with array_replace()
$new_array = array_fill_keys($ordering_array, NULL);
$new_array = array_replace($new_array, $given_array);
$new_array = array_filter($new_array);
Upvotes: 2