2

I have collection with subcollections like:

+
+--- name: 1a8 Lorem Ipsum
+
+--- name: 1a2 Lorem Ipsum
+
+--- name: 1a10 Lorem Ipsum

and now I want to sort it by this name:

$collection->sortBy('name')

It should be:

1a2 Lorem Ipsum
1a8 Lorem Ipsum
1a10 Lorem Ipsum

but I'm getting:

1a10 Lorem Ipsum
1a2 Lorem Ipsum
1a8 Lorem Ipsum

Why? I have tried too with $collection->sortBy('name', SORT_NATURAL, false) but it's same effect.

Paul
  • 411
  • 6
  • 15

2 Answers2

3

What might be happening is that because your values are starting with an integer, is that they are turned into an integer value. That means anything after the first non-numeric character is discared. In your case you're left with 3 1's

You might want to use a custom sorting callback that implements strnatcmp

$collection->sort(function($a, $b) {
   // using 3 = for type and value comparisan.
   if($a->name === $b->name) {
      return 0;
   };
   return strnatcmp($a->name, $b->name);
});
Tschallacka
  • 27,901
  • 14
  • 88
  • 133
2

The solution is already in the answer by @Tschallacka. if you want an explanation of why is this happening let me explain.

The function sortBy is receiving a string. String sorting is analyzed column by column (char position by char position). Integer or numeric type sorting, is analyzed by value.

So if we try to sort: 1,2,3,4,5,6,7,8,9,10,11,12,13... as string we would get something like: 1,10,11,..2,20,21.

Since you are mixing both, you need a solution like the one given already.

Erubiel
  • 2,934
  • 14
  • 32