0

I'm trying to sort an array of objects by name in Symfony. But I don't know how to do that, because the strings start with numbers so the order is not good.

I tried with a queryBuilder in my repository:

 $qb = $this->createQueryBuilder('arrondissement')
            ->addOrderBy('arrondissement.nom', 'ASC');
        $query = $qb->getQuery();
        return $query->execute();

And a sort() function in the controller,

But as you can see it's not totaly that. I wnat something like : 1er arrondissement, 2e ...., 20e..., Paris

enter image description here

DarkBee
  • 16,592
  • 6
  • 46
  • 58
Alizée
  • 23
  • 2
  • It is sorted in alphabetical order. The result you want is not an alphabetical order so you have to implement it yourself. `because the strings start with numbers so the order is not good.` what does this mean? – Code Spirit Aug 11 '20 at 12:12
  • the order of now is that it starts with all the 1 (1, 10, 11, 18 ...) then the 2 (2, 20 ...), 3, 4 ... While I want it to be 1,2,3,4 – Alizée Aug 11 '20 at 12:20

3 Answers3

0

You can use php natsort for example :

$arr = [
            '10e arrondrissement',
            '1e arrondrissement',
            '8e arrondrissement',
            '2e arrondrissement',
            '5e arrondrissement',
 ];
 natsort($arr);
 print_r($arr);

Will return :

Array ( 
[1] => 1e arrondrissement 
[3] => 2e arrondrissement 
[4] => 5e arrondrissement 
[2] => 8e arrondrissement 
[0] => 10e arrondrissement 
)
0

in this case IMHO you SHOULD NOT alter the ordering via PHP but use the database sorting for that.

Here is my proposal to modify your query builder:

 $qb = $this->createQueryBuilder('arrondissement')
            ->add( 'orderBy', 'CAST(arrondissement.nom AS UNSIGNED), arrondissement.nom')
        $query = $qb->getQuery();
        return $query->execute();
StFroyd
  • 53
  • 4
-1

you can't sort strings/objects by natural order easily in doctrine. but you could sort it in php:

$result = $query->getResult();
$nomSort = function($a, $b) :int {
    return strnatcmp($a->getNom(), $b->getNom());
}
usort($result, $nomSort);
// $result is now sorted

strnatcmp will compare according to "natural sort", which interprets "1" < "2" < "10" < "20", even if some more letters are appended.

usort can apply a custom sort function to an array - which is required here, since you want to access a sub-element (nom) of your array-element (an object). - Otherwise you could have just used natsort.

If you really need to sort in database for whatever reason, have a look at this related question: Natural Sort in MySQL (assuming mysql here)

Jakumi
  • 8,043
  • 2
  • 15
  • 32
  • Thank you for you response, but I have an error and I don't know how to resolve it :Call to a member function getNom() on int – Alizée Aug 11 '20 at 13:35
  • @Alizée oh, my bad, had a small error ... it should be uasort or usort instead of uksort. updated the answer to reflect that. – Jakumi Aug 11 '20 at 14:01