Sort a multidimensional array by values in a column
I have this array
Array
(
[0] => Array
(
[brand] => blah blah
[location] => blah blah
[address] => blah blah
[city] => blah blah
[state] => CA
[zip] => 90210
[country] => USA
[phone] => 555-1212
[long] => -111
[lat] => 34
[distance] => 3.08
)
[1] => Array
(
[brand] => blah blah
[location] => blah blah
[address] => blah blah
[city] => blah blah
[state] => CA
[zip] => 90210
[country] => USA
[phone开发者_如何学运维] => 555-1212
[long] => -111
[lat] => 34
[distance] => 5
)
.
.
.
}
I want to be able to sort the arrays in the hash by distance.
You need to extract all the distances first, then pass both the distance and the data to the function. As shown in example 3 in the array_multisort documentation.
foreach ($data as $key => $row) {
$distance[$key] = $row['distance'];
}
array_multisort($distance, SORT_ASC, $data);
This assumes you want the shortest distances first, otherwise change the SORT_ASC
to SORT_DESC
If you want to avoid the looping you can use the array_column
function to achieve your target.
For Example,
You want to sort below array with distance sort
$arr = array(
0 => array( 'lat' => 34, 'distance' => 332.08 ),
1 => array( 'lat' => 34, 'distance' => 5 ),
2 => array( 'lat' => 34, 'distance' => 34 )
);
Using below single line your array will be sort by distance
array_multisort( array_column( $arr, 'distance' ), SORT_ASC, SORT_NUMERIC, $arr );
Now, $arr contain with sorted array by distance
The advantage to calling usort()
instead of array_multisort()
, is that you don't need to pre-iterate the input array to generate an array of columnar data.
The following one-liner will use PHP7.4's arrow function syntax with PHP7's "spaceship operator" / "three-way comparison operator" to sort the input array (by reference) based on the distance column values.
With $a
on the left side of <=>
and $b
on the right side, ascending order is used. To achieve descending sorting, write $b['distance'] <=> $a['distance']
.
Code:
usort($array, fn($a, $b) => $a['distance'] <=> $b['distance']);
var_export($array);
To break ties while sorting, you can declare multiple values to sort on via arrays of values.
The following will sort by:
- distance ASC then
- country DESC then
- state ASC then
- city ASC
Code:
usort(
$array,
fn($a, $b) =>
[$a['distance'], $b['country'], $a['state'], $a['city']]
<=>
[$b['distance'], $a['country'], $b['state'], $b['city']]
);
Use can use usort;
function cmpDistance($a, $b) {
return ($a['distance'] - $b['distance']);
}
usort($array, "cmpDistance");
This code helps to sort the multidimensional array using array_multisort()
$param_dt = array();
foreach ($data_set as $key => $row) {
if(isset($row['params']['priority']))
{
$param_dt[$key] = $row['params']['priority'];
}
else
{
$param_dt[$key] = -2; // if priority key is not set for this array - it first out
}
}
array_multisort($param_dt, SORT_ASC,SORT_NUMERIC, $data_set);
Now $data_set
has the sorted list of elements.
We have an array of rows, but array_multisort() requires an array of columns, so we use the below code to obtain the columns, then perform the sorting.
// as of PHP 5.5.0 you can use array_column() instead of the above code
$brand= array_column($data, 'brand');
$city= array_column($data, 'city');
// Sort the data with volume descending, edition ascending
// Add $data as the last parameter, to sort by the common key
array_multisort($brand, SORT_DESC, $city, SORT_ASC, $data);
精彩评论