0

Possible Duplicate:
PHP sort multidimensional array by value

I have an array like this -

Array
(
    [0] => Array
        (
            [rest_id] => 1
            [restname] => Baumgart's Cafe
            [address] => 158 Franklin Avenue
            [distance] => 20.3599115829
        )

    [1] => Array
        (
            [rest_id] => 2
            [restname] => Brownstone Diner & Pancake Factory
            [address] => 426 Jersey Avenue
            [distance] => 12.422657991
        )

    [2] => Array
        (
            [rest_id] => 3
            [restname] => Jacques Torres Chocolate
            [address] => 285 Amsterdam Avenue
            [distance] => 16.3264917908
        )

    [3] => Array
        (
            [rest_id] => 4
            [restname] => Ed's Health Food
            [address] => 150 Mountain Avenue
            [distance] => 31.1066764629
        )

I want to sort this array on distance. Any help is appreciated. Thnak you.

Community
  • 1
  • 1
SandyK
  • 465
  • 1
  • 9
  • 28

4 Answers4

0

This needs to be done using usort and a callback.

function cmp($a, $b)
{
  $ret = ($a['distance'] - $b['distance']); // this should actually be a subtraction with a comparison to a small epsilon value due to inconsistencies with floating point arithmetic

  if ($ret)
  {
    $ret = ($ret > 0 ? 1 : -1);
  }

  return $ret;
}

usort($array, 'cmp');
evan
  • 12,307
  • 7
  • 37
  • 51
  • The comparison function must return an integer less than, equal to, or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second. – xdazz Sep 20 '11 at 06:00
  • This subarrays does not matter the result. The point is your callback should return an integer. – xdazz Sep 20 '11 at 06:07
  • check this. http://codepad.viper-7.com/HD6rG3 – xdazz Sep 20 '11 at 06:08
  • touche - php not handling floats in the callback for a comparison function is very lame. Answer fixed. – evan Sep 20 '11 at 06:21
  • More info about comparing floats with epsilon values here - basically 1.1 - 0.1 does not always come out to 1.0 which is why the epsilon trick is needed for accuracy: http://stackoverflow.com/questions/17333/most-effective-way-for-float-and-double-comparison – evan Sep 20 '11 at 06:23
  • 1
    This answer has logical errors. If the two distances are the same, you will (in a non-obvious way) return `-1` – Emil Vikström Sep 20 '11 at 06:26
  • @Emil - that is, actually, ok for the sorting - although not what was intended - fixed – evan Sep 20 '11 at 06:53
0
usort($array, function($a,$b){
    if ($a['distance'] === $b['distance']) {
        return 0;
    }
    return ($a['distance'] < $b['distance']) ? -1 : 1;
});
xdazz
  • 158,678
  • 38
  • 247
  • 274
  • thanks, might be helpful – SandyK Sep 20 '11 at 05:56
  • To the downvoter, please tell the reason. – xdazz Sep 20 '11 at 06:35
  • Actually, (likely due to compiler optimization) this answer, and both of my current answers run in the same number of operations. My original answer (simple subtraction) is, in fact, faster - but doesn't work correctly due to returning of floats rather than ints. Php just lost some of my respect. – evan Sep 20 '11 at 06:49
0
usort($array, function($a,$b){
    return (($a['distance'] == $b['distance']) ? 0 : (($a['distance'] > $b['distance']) ? 1 : -1));
});
Anush Prem
  • 1,511
  • 8
  • 16
0

Even though php says that it you should return 0 for equal answers, it is only necessary for resorting an already sorted array and preserving the previous sort as a "sub-sort". This does, in fact, work:

function cmp($a, $b) 
{
  return ($a['distance'] - $b['distance'] > 0 ? 1 : -1);
}

usort($array, 'cmp');

Example: http://codepad.viper-7.com/6RLCYM

evan
  • 12,307
  • 7
  • 37
  • 51