I have the following array in PHP which contains the lengths of 3 sides of a triangle:
$edge_lengths = array(
[0]=>
float(420)
[1]=>
float(593.9696961967)
[2]=>
float(420)
);
I now need to sort this array so that the values are sorted in reverse order (highest-to-lowest). If any values match then the array must further be sorted by key in reverse order (highest-to-lowest) to get the following result:
$edge_sorted = array(
[1]=>
float(593.9696961967)
[2]=>
float(420)
[0]=>
float(420)
);
In Python I can do this with one line of code like this:
edge_sorted = np.argsort(edge_lengths)[::-1]
Which will then return this:
[1 2 0]
Note that this just returns a list of the indexes; I don’t need the points as such.
My equivalent code in PHP to try and do the same thing is this:
asort($edge_lengths, SORT_NUMERIC); // sort values in ascending order
$edge_lengths = array_reverse($edge_lengths, true); // reverse array and preserve keys
$edge_sorted = array();
foreach ($edge_sorted as $key => $value) {
$edge_sorted[] = $key;
}
This code nearly works, but on some occasions where the values are the same the keys are still ordered lowest-to-highest rather than highest-to-lowest. I have considered trying to write a comparison function using usort
or uksort
but I don’t know where to start and would appreciate some help.
2
Answers
There is not a PHP function that can sort by key and value simultaneously, you need to convert the input into an array of pairs, sort that, and then translate it back into a keyed array.
Output:
That said, it would be simpler if you just stored the values as
[edge_id, edge_length]
pairs in the first place.You could use a custom sort function with
uksort
, sorting the keys based initially on the value at that location, and then (in case of equal values) on the key itself. You can then usearray_keys
to get the same result asargsort
.Output:
Demo on 3v4l.org