简体   繁体   中英

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

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);

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:

  1. distance ASC then
  2. country DESC then
  3. state ASC then
  4. city ASC

Code:

usort(
    $array,
    fn($a, $b) =>
        [$a['distance'], $b['country'], $a['state'], $a['city']]
        <=>
        [$b['distance'], $a['country'], $b['state'], $b['city']]
);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM