Assuming I have something coming back from a JSON request that essentially looks like this --

$data = array('0'=> array('name' => 'Dr. Smith',
                          'address' => '3002 Fake Ave.',
                          'lat' => '34.711158',
                          'lng' => '-137.803578',
                          'phone' => '714.939.1324'),
              '1' => array('name' => 'Dr. Paul',
                           'address' => '801 Fake St.',
                           'lat' => '31.749917',
                           'lng' => '-137.834388'));

How do I order it by one of the elements? Say if I wanted to sort the whole array of arrays by the Lat element? And put it back in the $data element, so I can keep working with it.

I've read the stuff on PHP about usort and sorting by a sub-array element, but when I try to work with their code examples they aren't working.

link|improve this question

To make the question sound less confusing, try calling them nested arrays. Just a suggestion – redelman431 yesterday
feedback

2 Answers

The callback function for usort will receive two of your array entries (which are arrays in themselves) and must answer whether $a comes before or after $b.

For example the function would receive

  $a = array('Lat' => 45, 'Name' => 'Mickey Mouse', ...)
  $b = array('Lat' => 47, ...)

So if you want to sort by Lat element, you would use,

  function sort_by_lat($a, $b)
  {
      return $a['Lat'] - $b['Lat']; // or b - a to sort the other way
  }

  usort($array, "sort_by_lat");

A problem you might have is that this way, if you sorted by longitude, you might consider -1 to be less than +1, and -179 to be less than +180. Which might or might not be what you expect. In this case you would need to use if(), and/or introduce some conversion.

To sort by name, you can do

 if ($a['field'] > $b['field']) return 1;
 if ($a['field'] == $b['field']) return 0;
 return -1;

(again invert +1 and -1 to get sorted the other way).

link|improve this answer
feedback

Don't forget all your data is coming in as strings, so you need to convert the number values to floats to do a proper comparison.

http://codepad.org/p2EMfTDR

$data = array('0'=> array('name' => 'Dr. Smith', 'address' => '3002 Fake Ave.', 'lat' => '20.711158', 'lng' => '10.803578', 'phone' => '714.939.1324'), '1' => array('name' => 'Dr. Paul', 'address' => '801 Fake St.', 'lat' => '10.749917', 'lng' => '20.834388'));

function cmpLat($a, $b)
{
    if(floatval($a['lat']) > floatval($b['lat'])) {
        return 1;
    } elseif(floatval($a['lat']) < floatval($b['lat'])) {
        return -1;
    } else {
        return 0;
    }
}

function cmpLng($a, $b)
{
    if(floatval($a['lng']) > floatval($b['lng'])) {
        return 1;
    } elseif(floatval($a['lng']) < floatval($b['lng'])) {
        return -1;
    } else {
        return 0;
    }
}

usort($data, "cmpLat");

print_r($data);

usort($data, "cmpLng");

print_r($data);
link|improve this answer
feedback

Your Answer

 
or
required, but never shown
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.