views:

111

answers:

5

Hi,

I have some difficulty sorting my array. It looks like this :

[0] => Array
        (
            [firstname] => Jnic
            [lastname] => Fortin
            [points] => Array
                (
                    [id] => 20453
                    [f] => 31
                    [r] => 7                 
                    [total] => 82
                )

        )

    [1] => Array
        (
            [firstname] => Kris
            [lastname] => Anders
            [points] => Array
                (
                    [id] => 20309                    
                    [f] => 0
                    [r] => 1
                    [total] => 56
                )

        )
[2] => Array
            (
                [firstname] => Em
                [lastname] => Zajo
                [points] => Array
                    (
                        [id] => 20339                    
                        [f] => 8
                        [r] => 3
                        [total] => 254
                    )

            )

I would like to sort it by "total" DESC. How could I do it? If everything sort ok the array would be order [2][0][1] (254,82,56)

Thanks

+4  A: 

You probably can use the usort function for that : it sorts an array, using a callback function to compare the elements of that array :

bool usort  ( array &$array  , callback $cmp_function  )

This function will sort an array by its values using a user-supplied comparison function. If the array you wish to sort needs to be sorted by some non-trivial criteria, you should use this function

If your function is defined to compare per $element['points']['total'], it should do the trick.


Edit : And here is the example, using uasort, which is the same as usort, but will keep the array keys, like pointed out by ryanday :

First, let's declare the array :

$a = array(
    array(
        'firstname' => 'Jnic',
        'lastname' => 'Fortin',
        'points' => array(
            'id' => 20453,
            'f' => 31,
            'r' => 7,
            'total' => 82,
        ),
    ),
    array(
        'firstname' => 'Kris',
        'lastname' => 'Anders',
        'points' => array(
            'id' => 20309,
            'f' => 0,
            'r' => 1,
            'total' => 56,
        ),
    ),
    array(
        'firstname' => 'Em',
        'lastname' => 'Zajo',
        'points' => array(
            'id' => 20339,
            'f' => 8,
            'r' => 3,
            'total' => 254,
        ),
    ),
);

And then, the comparison function :

function my_compare($a, $b) {
    if ($a['points']['total'] > $b['points']['total']) {
        return -1;
    } else if ($a['points']['total'] < $b['points']['total']) {
        return 1;
    }
    return 0;
}

And, finally, we use it :

uasort($a, 'my_compare');
var_dump($a);

And get the array, sorted by total desc :

array
  2 => 
    array
      'firstname' => string 'Em' (length=2)
      'lastname' => string 'Zajo' (length=4)
      'points' => 
        array
          'id' => int 20339
          'f' => int 8
          'r' => int 3
          'total' => int 254
  0 => 
    array
      'firstname' => string 'Jnic' (length=4)
      'lastname' => string 'Fortin' (length=6)
      'points' => 
        array
          'id' => int 20453
          'f' => int 31
          'r' => int 7
          'total' => int 82
  1 => 
    array
      'firstname' => string 'Kris' (length=4)
      'lastname' => string 'Anders' (length=6)
      'points' => 
        array
          'id' => int 20309
          'f' => int 0
          'r' => int 1
          'total' => int 56


ryanday > Thanks for your answer !

Pascal MARTIN
A: 

I noticed you said the proper array should be ordered [2][0][1], if that index association is important to you follow Pascal's advice with the uasort() function.

ryanday
+1  A: 

You will want to use usort as answered by @Pascal MARTIN, but here is the full code to achieve what you want:

function total_sort($a, $b){
    $a_total = $a['points']['total'];
    $b_total = $b['points']['total'];

    if($a_total == $b_total) return 0;

    return ($a_total > $b_total) ? -1 : 1;
}

usort($array, "total_sort");

EDIT: After I posted I saw @Pascal updated his answer to include a sample. Since I wrote my sort function a little different, I am leaving it here as another reference.

Doug Neiner
A: 

usort is a robust solution that can be very flexible for complex cases. Since your data set is relatively simple i would suggest the following:

// assuming your array has been defined in $a
$sort = array();
foreach ($a as $key => $suba)
{
    // this collects the values you want to sort by and associates them with the correct index
    $sort[$key] = $suba['points']['total'];
}
// this sorts the collected values
sort($sort);

// this re-sorts $a according to the sorted $sort array
array_multisort($a, $sort);

not sure about performance but this is at least AS GOOD as usort if not better

Janek
A: 

Thanks for the answer SO fast. Janek said "not sure about performance but this is at least AS GOOD as usort if not better"

Performance is really really important cause there will be sometime really huge array, so should I use the usort fonction or his?

Jean-Nicolas