6

I want to sort a multidimensionl array by one or more keys using the Laravel helper array_sort.

array(
    array('firstname_1','lastname_1'),
    array('firstname_2','lastnmae_2')
)

I want to order it first by firstname and then by lastname.

I also want to do this in DESC or ASC order. How can I achieve this?

There are functions aivalable in the internet to do this but I would like to understand how to use the Laravel helper. The doc for array_sort (http://laravel.com/docs/helpers#arrays) I don't find comprehensive.

almo
  • 6,107
  • 6
  • 43
  • 86
  • [krsort()](http://php.net/manual/en/function.krsort.php)? Remember that laravel is just PHP... – Marc B Jul 07 '14 at 14:28
  • I 'm not voting to close the question as a dupe because my vote would be decisive, but there's code (unrelated to Laravel) to do exactly what you want in one of my answers [here](http://stackoverflow.com/a/16788610/50079). If you feel it fully addresses your question please say so and then we can close it. – Jon Jul 07 '14 at 14:30
  • @Jon, I saw that and thanks for your very detailed post. I am asking in this question specificly about the Laravel helper, since I want to understand how to use it. I will stress this point more in my question. – almo Jul 07 '14 at 14:34
  • 1
    @almo: All right. Unfortunately I'm almost certain the answer would then be "the Laravel helper simply doesn't allow that". – Jon Jul 07 '14 at 14:36
  • That helper would only allow you to sort by a single column. What you will need is `array_multisort()` but a much better way would be to sort it in your query if that's how you are retrieving this data. – user1669496 Jul 07 '14 at 15:30

2 Answers2

5

The array_sort() helper function is a very thin wrapper around the default Illuminate\Support\Collection::sortBy() method. Excluding comments, this is all that it does:

function array_sort($array, Closure $callback)
{
    return \Illuminate\Support\Collection::make($array)->sortBy($callback)->all();
}

While handy, it is limiting in its sorting capabilities. Similarly, the Collection class will allow you to change sort direction, but not much else.

In my opinion, you have two options:

  1. Skip a Laravel-only solution and use some normal PHP and array_multisort(). As @Jon commented, there's some great details in this SO question.

  2. Use a combination of grouping and sorting in a Collection object to achieve the results you want.

I'd just stick with #1.

dustbuster
  • 79,958
  • 7
  • 21
  • 41
Aken Roberts
  • 13,012
  • 3
  • 34
  • 40
  • I am updating a site from laravel 4.2 to 6.5 and this was really helpful! I added the forward slash in front of the "Illuminate" because I got an error initially. This code is tested in a laravel environment. – dustbuster Jan 03 '20 at 19:13
4

Just as an example how to sort by first name and then by last name with the sort helper of Laravel.

First define some more example data:

$array = array(
    array('firstname_1','lastname_1'),
    array('firstname_2','lastname_3'),
    array('firstname_2','lastname_2'),
    array('firstname_3','lastname_3'),
);

In our closure we want to sort by first name first, and then by last name. Laravel will sort by the returned values of the closure. So in your case the trick is to concatenate both strings:

$array = array_sort($array, function($value) {
    return sprintf('%s,%s', $value[0], $value[1]);
});

Internally Laravel will now sort the contents of this intermediate array:

$intermediateArray = array(
    'firstname_1,lastname_1',
    'firstname_2,lastname_3',
    'firstname_2,lastname_2',
    'firstname_3,lastname_3',
);

This will result in an array which is sorted by first name and than by last name in ascending order.

To use descending order you need first sort the array and than reverse it:

$array = array_reverse(array_sort($array, function($value) {
    return sprintf('%s,%s', $value[0], $value[1]);
}));
maxwilms
  • 1,964
  • 20
  • 23