dst11
dst11

Reputation: 161

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.

Upvotes: 16

Views: 37954

Answers (6)

mickmackusa
mickmackusa

Reputation: 47904

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

Upvotes: 4

Ashish
Ashish

Reputation: 83

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

Upvotes: 1

Chirag Viradiya
Chirag Viradiya

Reputation: 487

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

Upvotes: 16

Karthikeyan Ganesan
Karthikeyan Ganesan

Reputation: 2035

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.

Upvotes: 1

Czechnology
Czechnology

Reputation: 14992

Use can use usort;

function cmpDistance($a, $b) {
    return ($a['distance'] - $b['distance']);
}

usort($array, "cmpDistance");

Upvotes: 2

Jacob
Jacob

Reputation: 8334

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

Upvotes: 25

Related Questions