php sort array by another array
Sort an Array by keys based on another Array?
Is it possible in PHP to do something like this? How would you go about writing a function? Here is an example. The order is the most important thing.
And I’d like to do something like
Because at the end I use a foreach() and they’re not in the right order (because I append the values to a string which needs to be in the correct order and I don’t know in advance all of the array keys/values).
I’ve looked through PHP’s internal array functions but it seems you can only sort alphabetically or numerically.
16 Answers 16
PS: I’m answering this ‘stale’ question, because I think all the loops given as previous answers are overkill.
How about this solution
Another way for PHP >= 5.3.0:
Works fine with string and numeric keys.
Take one array as your order:
You can sort another array based on values using array_intersect Docs :
Or in your case, to sort by keys, use array_intersect_key Docs :
Both functions will keep the order of the first parameter and will only return the values (or keys) from the second array.
So for these two standard cases you don’t need to write a function on your own to perform the sorting/re-arranging.
IF you have array in your array, you’ll have to adapt the function by Eran a little bit.
PHP has functions to help you with this:
Usort does all the work for you and array_search provides the keys. array_search() returns false when it can’t find a match so items that are not in the sort array naturally move to the bottom of the array.
Note: uasort() will order the array without affecting the key => value relationships.
Sort array value by another array key
I want to sort 1st array by 2nd array’s key, so final result is an array like this:
I must confess that I’m relative new to PHP and MySQL. Hopefully some one of you all could bring me back on track.
5 Answers 5
You can write a custom sort function that references a map (inversed second array):
This will do what you want in one line:
To explain: Since you want to sort by the value in the array, and not by the key, we use array_flip to flip the array and value in each of your arrays. Then, we use array_replace to replace the values in the second array with the matching ones from the first array (keeping the current order). Then we use array_flip to put the keys and values back how we started.
your code can be something like this:
Not the answer you’re looking for? Browse other questions tagged php arrays sorting or ask your own question.
Related
Hot Network Questions
Subscribe to RSS
To subscribe to this RSS feed, copy and paste this URL into your RSS reader.
site design / logo © 2021 Stack Exchange Inc; user contributions licensed under cc by-sa. rev 2021.9.17.40238
By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.
Sorting Arrays
PHP has several functions that deal with sorting arrays, and this document exists to help sort it all out.
The main differences are:
Function name | Sorts by | Maintains key association | Order of sort | Related functions |
---|---|---|---|---|
array_multisort() | value | string keys yes, int keys no | first array or sort options | array_walk() |
asort() | value | yes | ascending | arsort() |
arsort() | value | yes | descending | asort() |
krsort() | key | yes | descending | ksort() |
ksort() | key | yes | ascending | krsort() |
natcasesort() | value | yes | natural, case insensitive | natsort() |
natsort() | value | yes | natural | natcasesort() |
rsort() | value | no | descending | sort() |
shuffle() | value | no | random | array_rand() |
sort() | value | no | ascending | rsort() |
uasort() | value | yes | user defined | uksort() |
uksort() | key | yes | user defined | uasort() |
usort() | value | no | user defined | uasort() |
User Contributed Notes 3 notes
While this may seem obvious, user-defined array sorting functions ( uksort(), uasort(), usort() ) will *not* be called if the array does not have *at least two values in it*.
The following code:
string(4) «val3»
string(4) «val2»
The first array doesn’t get sent to the function.
Please, under no circumstance, place any logic that modifies values, or applies non-sorting business logic in these functions as they will not always be executed.
Another way to do a case case-insensitive sort by key would simply be:
Stabilizing the sort functions (in this case, usort).
How to sort an array of associative arrays by value of a given key in PHP?
20 Answers 20
Here’s an example taken straight from the manual and adapted to your case:
As of PHP 5.5.0 you can use array_column() instead of that foreach:
PHP 7+
As of PHP 7, this can be done concisely using usort with an anonymous function that uses the spaceship operator to compare elements.
You can do an ascending sort like this:
Or a descending sort like this:
To understand how this works, note that usort takes a user-provided comparison function that must behave as follows (from the docs):
The comparison function must return an integer less than, equal to, or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second.
which is exactly what usort needs. In fact, almost the entire justification given for adding to the language in https://wiki.php.net/rfc/combined-comparison-operator is that it
makes writing ordering callbacks for use with usort() easier
PHP 5.3+
PHP 5.3 introduced anonymous functions, but doesn’t yet have the spaceship operator. We can still use usort to sort our array, but it’s a little more verbose and harder to understand:
Returning non-integer values from the comparison function, such as float, will result in an internal cast to integer of the callback’s return value. So values such as 0.99 and 0.1 will both be cast to an integer value of 0, which will compare such values as equal.
This is an important trap to bear in mind when using usort in PHP 5.x! My original version of this answer made this mistake and yet I accrued ten upvotes over thousands of views apparently without anybody noticing the serious bug. The ease with which lackwits like me can screw up comparator functions is precisely the reason that the easier-to-use spaceship operator was added to the language in PHP 7.
Sorting a php array of arrays by custom order
I have an array of arrays:
The need to go in a specific order:
How would I go about doing that? I have sorted arrays before, and read plenty of other posts about it, but they are always comparison based (i.e. valueA Follow
7 Answers 7
The example below uses a closure to make life easier.
Finally, there is no special reason for using a closure; it’s just my go-to way of writing these sorts of throwaway functions quickly. It could equally use a normal, named function.
Extending salathe’s answer for this additional requirement:
Now what happens when I add items to the array and not to the sort? I don’t care what order they appear, as long as it comes after the ones that I did specify.
You need to add two additional conditions in the sorting function:
So the revised code would be:
You need to define your own comparison function and use usort or uasort if you want to maintain index association.
More Efficient Solution
Don’t recalculate positions on every comparison
When your array is large or getting the id is costlier, using usort() can get bad, because you recalculate the id for each comparison. Try array_multisort() with pre-calculated positions (see mediumsort or fastsort in the example below), which isn’t any more complicated.
Also searching for the id in the order array on each comparison (like in the accepted answer) doesn’t improve performance, since you iterate over it every comparison. Calculate it once.
In the code snippet below you can see the main three sorting functions:
You can more generally sort an array by a weight (see weightedsort in the example). Make sure to calculate the weight only once, to achieve good performance.
Performance (for an array of length 1000)
Hint: For larger arrays the difference gets worse.
Sorting Function Comparison
Without sort you also can get it.
@salathe For those of you that are having a hard time understanding what salathe’s usort is doing:
Then there is the fight at the return. Now we look to see if having more or less of the attribute is better. In a usort battle the home champion wants a negative number so he can be sooner in the array. The away champion wants a positive number. And should there be a 0 it is a tie.
Code would look like:
note: code is run many times much like a real tournament has many battles in order to decide who gets first(ie 0 / start of array)