1

I am looking to do some complex array sorting, but I have no idea where to start. The inner array has three relevant keys for sorting: first the year (numerical ASC), then the month (numerical ASC) and finally the name (alphabetical DESC).

<?php
// the current array:
$array = (
  array('year'=>2012, 'month'=>3, 'name'=>'John', 'score'=>12),
  array('year'=>2013, 'month'=>8, 'name'=>'Paul', 'score'=>3),
  array('year'=>2013, 'month'=>5, 'name'=>'Dennis', 'score'=>7),
  array('year'=>2012, 'month'=>3, 'name'=>'Paul', 'score'=>5),
  array('year'=>2012, 'month'=>12, 'name'=>'Paul', 'score'=>9),
  array('year'=>2012, 'month'=>9, 'name'=>'Mitt', 'score'=>3)
);

// I want to do some sorting with this as output:
$array = (
  array('year'=>2012, 'month'=>3, 'name'=>'John', 'score'=>12),
  array('year'=>2012, 'month'=>3, 'name'=>'Paul', 'score'=>5),
  array('year'=>2012, 'month'=>9, 'name'=>'Mitt', 'score'=>3),
  array('year'=>2012, 'month'=>12, 'name'=>'Paul', 'score'=>9),
  array('year'=>2013, 'month'=>5, 'name'=>'Dennis', 'score'=>7),
  array('year'=>2013, 'month'=>8, 'name'=>'Paul', 'score'=>3)
);
?>

If anyone can point me in the right direction that is really appreciated ;-).

1
  • usort() Commented Jul 12, 2013 at 23:50

3 Answers 3

3

This should work...

<?php
    // Obtain a list of columns
    // PHP 5 >= 5.5.0
    $years  = array_column($array, 'year');
    $months = array_column($array, 'month');
    $names  = array_map('strtolower', array_column($array, 'name')); // because it's a string sort.

    // Sort the data with volume descending, edition ascending
    // Add $data as the last parameter, to sort by the common key
    array_multisort($years, SORT_ASC, $months, SORT_ASC, $names, SORT_DESC, $array);
?>

From: http://www.php.net/manual/en/function.array-multisort.php

EDIT : for PHP < 5.5

<?php
    // Obtain a list of columns
    // PHP < 5.5.0
    foreach ($array as $key => $row) {
        $years[$key]  = $row['year'];
        $months[$key] = $row['month'];
        $names[$key]  = strtolower($row['name']); // because it's a string sort.
    }
?>
5
  • This works perfectly, didn't hear of array_multisort before. Thanks, will accept your answer in a few minutes (when it's allowed). Commented Jul 13, 2013 at 0:01
  • Maybe you should also use a map function on the $names array if you're not sure to always have the first letter in uppercase. ($names_lowercase = array_map('strtolower', $names);) This is just used for the array_multisort function and don't change your original Array() Commented Jul 13, 2013 at 0:05
  • Do you mean that without your suggestion for example a lowercase 'a' is sorted behind an uppercase 'Z'? Commented Jul 13, 2013 at 0:13
  • 1
    Yes, I do. I edited the source should you like this version ;-) Commented Jul 13, 2013 at 0:26
  • array_column() is only available since PHP 5.5. Using usort() is way better: It is only one sort call, and the only variable thing is the comparison "what comes first" that is completely coded in one other function. It is easier to maintain. The cases where you absolutely must use array_multisort() are very rare, and this is not one of them. Commented Jul 13, 2013 at 11:42
1

Take a look at usort. It accepts a callback in which you can implement a custom comparison of two items. Apart from usort, there's also uasort and uksort, which accept callbacks, but in this case you'll need usort.

1
  • Looking into it now, guess I can figure it out from here! Commented Jul 12, 2013 at 23:53
1

You need 'array_multisort' function.

Its in the manual.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.