Reputation: 3275
What I'm trying to do is sort a multi-dimensional array that contains decimal values. From what I've tested, floats are having trouble being ordered properly.
Array
(
[0] => Array
(
[company] => Ebay
[weight] => 4.6
)
[1] => Array
(
[company] => Ebay
[weight] => 1.7
)
[2] => Array
(
[company] => Ebay
[weight] => 3.7
)
)
usort($array, 'order_by_weight');
// Sorts DESC highest first
function order_by_weight($a, $b) {
return $b['weight'] - $a['weight'];
}
What is the best way to sort these numbers in descending?
Upvotes: 8
Views: 9143
Reputation: 47991
None of the earlier posted answers are demonstrating the most modern syntaxes for sorting by a column value.
If using usort()
, use the three-way comparison operator ("spaceship operator ") from PHP7 and if you are on PHP7.4 or higher enjoy the brevity of "arrow function" syntax. For descending directional sorting write $b
on the left of the operator and $a
on the right. (Demo)
usort($arr, fn($a, $b) => $b['weight'] <=> $a['weight']);
array_multisort()
can also be used, but it requires an additional loop to isolate a column of data. (Demo)
array_multisort(array_column($arr, 'weight'), SORT_DESC, $arr);
Upvotes: 0
Reputation: 11853
As sorting algo here is good example for sort multi dimension array without using any more inbuilt php function
$multiarr = array('0'=>array(
"hashtag" => "a7e87329b5eab8578f4f1098a152d6f4",
"title" => "Flower",
"order" => 3),
'1' => array(
'hashtag' => "b24ce0cd392a5b0b8dedc66c25213594",
"title" => "Free",
"order" => 2),
'2' => array('hashtag' => 'e7d31fc0602fb2ede144d18cdffd816b',
'title' => 'Ready',
'order' => 1
));
sorting function :
function multisort(&$array, $key) {
$valsort = array();
$ret = array();
reset($array);
foreach ($array as $ii => $va) {
$valsort[$ii] = $va[$key];
}
asort($valsort);
foreach ($valsort as $ii => $va) {
$ret[$ii] = $array[$ii];
}
$array = $ret;
}
multisort($multiarr, "order");
: output :
Array
(
[2] => Array
(
[hashtag] => e7d31fc0602fb2ede144d18cdffd816b
[title] => Ready
[order] => 1
)
[1] => Array
(
[hashtag] => b24ce0cd392a5b0b8dedc66c25213594
[title] => Free
[order] => 2
)
[0] => Array
(
[hashtag] => a7e87329b5eab8578f4f1098a152d6f4
[title] => Flower
[order] => 3
)
)
Upvotes: 0
Reputation: 51
In case someone wants a more concise code, especially to handle equals condition you will add if condition before @zerkms's solution
using ceil
will round fractions up and will sort the decimal numbers correctly
usort($data, function($a, $b)
{
return ceil($a[$_GET['sortby']] - $b[$_GET['sortby']]);
});
Upvotes: 0
Reputation: 6345
You can do this with anonymous function in just one line
$arr = array(
array('company' => 'A', 'weight' => 4.6),
array('company' => 'B', 'weight' => 1.7),
array('company' => 'C', 'weight' => 3.7),
);
usort($arr, function($a, $b) { return $b['weight'] > $a['weight'] ;});
print_r($arr);
Hope this helps :)
Upvotes: 3
Reputation: 255015
$arr = array(
array('company' => 'A', 'weight' => 4.6),
array('company' => 'B', 'weight' => 1.7),
array('company' => 'C', 'weight' => 3.7),
);
usort($arr, 'order_by_weight');
function order_by_weight($a, $b) {
return $b['weight'] > $a['weight'] ? 1 : -1;
}
var_dump($arr);
PS: it's not a rocket science - this exact "trick" is used as the first example at http://php.net/usort
Upvotes: 21
Reputation: 2335
You can sort the array using array_multisort, altough, this is often used to sort on multiple array values instead of one.
echo "<pre>";
$a = array(
array('company' => 'ebay', 'weight' => 4.6),
array('company' => 'ebay', 'weight' => 1.7),
array('company' => 'ebay', 'weight' => 3.7),
array('company' => 'ebay', 'weight' => 2.7),
array('company' => 'ebay', 'weight' => 9.7),
array('company' => 'ebay', 'weight' => 0.7),
);
$company = array();
$weight = array();
foreach($a as $key=>$val) {
array_push($company, $val['company']);
array_push($weight, $val['weight']);
}
array_multisort($weight, SORT_ASC, $a);
print_r($a);
Upvotes: 1