Использование array_multisort () и установка пустых значений последними, а не первыми - PullRequest
2 голосов
/ 19 марта 2012

У меня есть 4 массива, и я использую array_multisort, чтобы отсортировать их все одновременно относительно друг друга.Проблема в том, что в первом массиве могут быть пустые значения, и я хочу поместить их в конец, а не в начало.

Пример: http://codepad.org/V6TjCsS5

Есть ли способ:

  • Передать пользовательскую функцию в array_multisort или
  • Сортировать первый массив с помощью пользовательской функции, а затем использовать порядок результата для сортировки других массивов или
  • Использовать определенныйаргумент с array_multisort для достижения того, что я хочу

Большое спасибо

Ответы [ 3 ]

3 голосов
/ 19 марта 2012

К сожалению, ни один из подходов, предлагаемых вами, невозможен, а это значит, что вы должны сделать еще один шаг назад и искать альтернативы.Я предполагаю, что вы хотите нормальную сортировку по возрастанию, с явным исключением, что пустые элементы (которые вы «самые маленькие») должны рассматриваться как «самые большие».

Вариант 1. Ручная перестановка элементов после сортировки

Сделайте ваш array_multisort как обычно, а затем внесите необходимые изменения:

// $arr1, $arr2 etc have been sorted with array_multisort
while(reset($arr1) == '') {
    $k = key($arr1);
    unset($arr1[$k]); // remove empty element from beginning of array
    $arr1[$k] = ''; // add it to end of array
    // and now do the same for $arr2
    $v = reset($arr2);
    $k = key($arr2);
    unset($arr2[$k]);
    $arr2[$k] = $v;
    // the same for $arr3, etc
}

Вы можете вытащить часть кода в функцию, чтобы сделать это красивее:

function shift_and_push(&$arr) {
    $v = reset($arr);
    $k = key($arr);
    unset($arr[$k]);
    $arr[$k] = $v;
}

Вариант 2: сконденсировать все внутри одного массива, чтобы вы могли использовать usort

Идея состоит в том, чтобы собрать все ваши массивы в один, чтобы вы могли указать функцию сравнения с помощью usort:

$allArrays = array_map(function() { return func_get_args(); },
                       $array1, $array2 /* , as many arrays as you want */);

Теперь вы можете сортировать:

// writing this as a free function so that it looks presentable
function cmp($row1, $row2) {
    // $row1[0] is the item in your first array, etc
    if($row1[0] == $row2[0]) {
        return 0;
    }
    else if($row1[0] == '') {
        return 1;
    }
    else if($row2[0] == '') {
        return -1;
    }

    return $row1[0] < $row2[0] ? -1 : 1;
}

usort($allArrays, "cmp");

На данный момент у вас есть массив, каждый элемент (строка) которого является массивом.Первые элементы каждого - это то, что изначально было в $array1, вторые элементы - то, что было в $array2 и т. Д. Поместив эти элементы в «строки», нам удалось сохранить порядок сортировки среди всех ваших исходных массивов синхронизированным.

0 голосов
/ 19 марта 2012

Вы действительно хотите пустые элементы? Просто удалите их перед сортировкой:

foreach($array1 as &$v) {
    if($v==='')
    {
        unset($v);
    }
}
0 голосов
/ 19 марта 2012

Вторым аргументом для array_multisort могут быть параметры сортировки. Таким образом, вы можете передать SORT_DESC, если SORT_ASC делает то, что вам нужно.

array_multisort($arr, SORT_DESC);

Для полноты, вот другие варианты SORT_ASC, SORT_DESC, SORT_REGULAR, SORT_NUMERIC, SORT_STRING. SORT_STRING может быть полезным.

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