Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP sorting multidimensional array, can only sort one column

Firstly, YES, this is a duplicate issue that's been asked 100 times on here, and I've read through many of the posts, but the examples given aren't working 100% for me and I can't figure out where I'm going wrong.

I want to sort an array like this by the 'distance' key, and I want the sort to be "expanded" across the entire array so it reorders all keys in the array. In essence, just like you'd get if you sorted a column in a spreadsheet and expanded the sort across all columns.

Here's the sample array:

$locations = array ( 
[phone] => Array ( 
    [0] => 555-123-1234 
    [1] => 555-456-4321 
    [2] => 555-789-1122 
    [3] => 555-321-1111 ) 
[address] => Array ( 
    [0] => 123 Main Street BigCity, NY 12345
    [1] => 456 Maple Street Somewhere, UT 87654
    [2] => 999 1st Ave MyTown, VA 23456
    [3] => 321 2nd Ave MyTown, VA 23456 ) 
[distance] => Array ( 
    [0] => 24.56
    [1] => 13.05
    [2] => 23.99
    [3] => 1.75 ) 
[name] => Array ( 
    [0] => First Location
    [1] => Second Location
    [2] => Third Location
    [3] => Fourth Location ) 
)

I'm trying to sort the array by 'distance', and I've tried using both the array_multisort() function and the usort() function ...but only "multisort" gives me nearly usable results by sorting the distances only and not sorting the entire array according to distance.

My function:

array_multisort($locations['distance'], SORT_NUMERIC);

I then run a "for" loop to traverse the array and spit out the values by key. The result is the distances are ordered but the Location names, addresses, etc. don't get reordered.

What am I missing here??

Thanks!!

like image 540
gtr1971 Avatar asked Mar 21 '26 07:03

gtr1971


1 Answers

Your array is arranged in columns, whereas array_multisort() when used in this way expects it to be arranged in rows.

It should be in the structure that you would get if you did:

$rows = array();
while ($row = $result->fetch_assoc()) $rows[] = $row;

...with a MySQLi result object.

You can reformat your existing array into this structure quite easily:

$locationsAsRows = array();
for ($i = 0; isset($locations['phone'][$i]); $i++) {
  $locationsAsRows[$i] = array (
    'phone' => $locations['phone'][$i],
    'address' => $locations['address'][$i],
    'distance' => $locations['distance'][$i],
    'name' => $locations['name'][$i]
  );
}
var_dump($locationsAsRows);

Now, when you do:

array_multisort($locations['distance'], SORT_NUMERIC, $locationsAsRows);
var_dump($locationsAsRows);

...you can see that the data has been sorted. Note that not only did I pass the column data you wanted to sort by, I also passed the whole "row formatted" $locationsAsRows array as the last argument. This is passed by reference, so $locationsAsRows itself will be the sorted data after you have called array_multisort().

Now let's say that two of the distance values are the same - we need to supply a second priority search column. So next, we could sort by address, and we can do that like so:

array_multisort($locations['distance'], SORT_NUMERIC, $locations['address'], SORT_ASC, $locationsAsRows);

See it working and have a play around with it...

like image 131
DaveRandom Avatar answered Mar 22 '26 23:03

DaveRandom



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!