PHP - Many uasort functions break sorting

I have a multidimensional array in which people are stored.

Array ( id93294 => (array ( Name => "Tom Anderson", Birthday => "03/17/1975"), id29349 => (array ( Name => "Tom Anderson", Birthday => "03/17/1975") ) 

It seems to be this, except for more information for people, so I want to sort by birthdays THEN first on a different basis (if their hometown matches their current location), but as soon as I do the second sorting by array, it loses the first grade, I used birthdays ...

How can I sort several times without spoiling my previous varieties.

PS I am using uasort.

+3
source share
2 answers

Update

I recently answered this question in a much more capable way in the "final" topic on sorting multidimensional arrays. You can safely read the rest of this answer and immediately follow the link for a more efficient solution.

Original answer

The uasort function allows you to define your own comparison function. Just indicate all the criteria you want in this.

For example, to sort by birthday, and then by name:

 function comparer($first, $second) { // First see if birthdays differ if ($first['birthday'] < $second['birthday']) { return -1; } else if ($first['birthday'] > $second['birthday']) { return 1; } // OK, birthdays are equal. What else? if ($first['name'] < $second['name']) { return -1; } else if ($first['name'] > $second['name']) { return 1; } // No more sort criteria. The two elements are equal. return 0; } 

I ignore the fact that in your example, the birthdays are not in a format that can be ordered by simple comparison using the < operator. In practice, you first convert them to a trivially compatible format.

Update: if you think keeping a bunch of these multicriteria collators can get ugly, you'll find me in agreement. But this problem can be solved like any other in computer science: just add another level of abstraction.

I will assume PHP 5.3 for the following example to use the convenient syntax of the anon function. But basically you can do the same with create_function .

 function make_comparer() { $criteriaNames = func_get_args(); $comparer = function($first, $second) use ($criteriaNames) { // Do we have anything to compare? while(!empty($criteriaNames)) { // What will we compare now? $criterion = array_shift($criteriaNames); // Do the actual comparison if ($first[$criterion] < $second[$criterion]) { return -1; } else if ($first[$criterion] > $second[$criterion]) { return 1; } } // Nothing more to compare with, so $first == $second return 0; }; return $comparer; } 

Then you can:

 uasort($myArray, make_comparer('birthday', 'name')); 

This example may be trying to be too smart; In general, I do not like to use functions that do not accept their arguments by name. But in this case, the use case is a very strong argument in favor of being too smart.

+6
source

Great question.

This pseudo code is based on the definition of the problem you specified and is intended for the callback function specified by uasort . I can’t fill in the details because you omitted the code you are using; I hope this leads you on the right track.

 function compare(p1, p2): if birthdays of p1 and p2 are not the same compare by birthday else compare by hometown 

If someone can verify that this is a valid comparison function for the sorting algorithm in the comments, I would appreciate it.

+1
source

Source: https://habr.com/ru/post/897141/


All Articles