PHP - Многочисленные функции uasort прерывают сортировку - PullRequest
4 голосов
/ 04 марта 2011

У меня есть многомерный массив, в котором хранятся люди.

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

Вроде как, за исключением дополнительной информации о людях, поэтому я хочу сначала отсортировать по дням рождения, ТО сортировать по другому атрибуту (если их родной городсоответствует их текущему местоположению), но как только я делаю вторую сортировку в массиве, она теряет первую сортировку, которую я делала, используя дни рождения ...

Как сортировать несколько раз, чтобы это не испортило мои предыдущие сортировки.

PS Я использую uasort.

Ответы [ 2 ]

6 голосов
/ 04 марта 2011

Обновление

Я недавно ответил на этот вопрос гораздо более умелым способом в "окончательной" теме о сортировке многомерных массивов.Вы можете спокойно пропустить прочтение оставшейся части этого ответа и сразу перейти по ссылке, чтобы найти гораздо более подходящее решение.

Исходный ответ

Функция uasort позволяет определить собственную функцию сравнения.Просто поместите в него все критерии, которые вы хотите.

Например, сортировать по дню рождения, а затем по имени:

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;
}

Я игнорирую тот факт, что в вашем примере дни рожденияне в формате, который можно заказать простым сравнением с использованием оператора <.На практике вы сначала конвертируете их в тривиально сопоставимый формат.

Обновление: Если вы считаете, что поддержание группы этих многокритериальных компараторов может быть ужасно быстрым, вы найдете меняв соглашении.Но эта проблема может быть решена как любая другая в компьютерной науке: просто добавьте еще один уровень абстракции.

Я буду использовать PHP 5.3 для следующего примера, чтобы использовать удобный синтаксис анон-функции.Но в принципе вы можете сделать то же самое с 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;
}

Затем вы можете сделать:

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

Этот пример, возможно, пытается быть слишком умным;в общем, я не люблю использовать функции, которые не принимают свои аргументы по имени.Но в этом случае сценарий использования является очень веским аргументом для того, чтобы быть слишком умным.

1 голос
/ 04 марта 2011

Отличный вопрос.

Этот псевдокод взят из определения проблемы, которую вы задали, и предназначен для функции обратного вызова, переданной uasort. Я не могу заполнить детали, потому что вы пропустили код, который используете; надеюсь, это приведет вас на правильный путь.

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

Если бы кто-то мог проверить, что это действительная функция сравнения для алгоритма сортировки в комментариях, я был бы признателен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...