Reputation: 5840
Finding the right title for this was next to impossible.
Imagine this scenario:
We have an array that contains certain product tags. The key is each tag's unique id and the value is its label:
Available Tags
Array (
[3] => Sweet
[4] => Sour
[5] => Bitter
[6] => Winter
[7] => Organic
)
We have another array which contains the tags that have been selected. The selection has a specific order which is defined by the key, while the value represents the id (of the actual tag we see in array #1).
Selected Tags in Specific Order
Array (
[10] => 4
[20] => 3
[30] => 7
)
My theoretical Approach
Certainly i could go about foreach-ing through the second array, collecting the appropriate values (that correspond to the first array's entries) in a new array. Then i could iterate over the first array and add all the values (to the new array) which are not yet present in the new array.
Quite honestly - that doesn't feel very professional. Unfortunately, i have no idea how to do this better.
Question
How can i neatly sort the first array (Available Tags) by using the chronology defined by the second array (Selected Tags)?
Note
I want to end up with all items from the first array. Not just the ones that are listed in the second one.
In case someone's curious: this is for multiple-selects which are sortable. Items which have been selected are sortable and must therefore appear in the right order. The other items order doesn't matter. My server-side data handler class gives me these two arrays as described, so that's what i got to work with.
Upvotes: 1
Views: 195
Reputation: 2663
Here's a solution that uses uksort()
. Elements of the $tags
array that are not present in the $order
array are sorted to the end, and the relative order between them is undefined.
function my_sort($a, $b) {
global $order;
if(in_array($a, $order)) {
if(in_array($b, $order)) {
// Both $a and $b have an order
return array_search($a, $order) - array_search($b, $order);
}
else {
// Only $a has an order, so it goes before $b
return -1;
}
}
else if(in_array($b, $order)) {
// Only $b has an order, so it goes before $a
return 1;
}
else {
// Neither $a or $b has an order, so we don't care how they're sorted
return 0;
}
}
uksort($tags, 'my_sort');
Upvotes: 1