Как отсортировать многомерный (2 уровня) массив по одному из элементов, по возр.. Но если у дочернего отсутствует элемент, то он встал в конец

242
12 февраля 2020, 09:10

Вот, есть такой массив

 $material_weights = array(
    0 => array(
        'nid' => 54545,
        'weight' => 0
    ),
    1 => array(
        'nid' => 545,
    ),
    2 => array(
        'nid' => 225,
        'weight' => 4
    ),
    3 => array(
        'nid' => 6,
        'weight' => 1
    ),
    4=> array(
        'nid' => 6,
    ),
    5 => array(
        'nid' => 6,
        'weight' => 3
    ),
)

Нужно отсортировать его по полю 'weight', по возрастанию, так чтобы все элементы у которых, нет поля 'weight', поставились в конец. Но лучше, чтобы сохранили свою первоначальную последовательность, то есть 1 и 6 элементы должны вставить в конец, но 1 все так же должен идти перед 6

Answer 1

Если порядок элементов у которых нет поля 'weight' не важен:

usort($material_weights, function($a, $b) {
    return ($a['weight'] ?? null) <=> ($b['weight'] ?? null);
});

Если важно сохранить порядок следования:

//array_filter сохраняет ключи
$have_not_weight = array_filter($material_weights, function($val) {
    return !isset($val['weight']);
});
$material_weights = array_diff_key($material_weights, $have_not_weight);
usort($material_weights, function($a, $b) {
    return ($a['weight'] ?? null) <=> ($b['weight'] ?? null);
});
$material_weights = array_merge($material_weights, $have_not_weight);
Answer 2

Ну как то так наверно -

usort($material_weights, function($a, $b) {
    if(isset($a['weight'])&&isset($b['weight'])) {
         return $a['weight'] <=> $b['weight']; // return $a['weight'] - $b['weight'];
    } elseif(!isset($a['weight'])) {
         return 1;
    } elseif(!isset($b['weight'])) {
         return -1;
    }
});

вторую часть вопроса не понял.

Array
(
[0] => Array
    (
        [nid] => 54545
        [weight] => 0
    )
[1] => Array
    (
        [nid] => 6
        [weight] => 1
    )
[2] => Array
    (
        [nid] => 6
        [weight] => 3
    )
[3] => Array
    (
        [nid] => 225
        [weight] => 4
    )
[4] => Array
    (
        [nid] => 6
    )
[5] => Array
    (
        [nid] => 545
    )
)
Answer 3

Самый простой способ, это пройтись по всему массиву и сортировать элементы по вашей необходимости. В случае, если элемент массива не содержит weight, то вырезать этот элемент в новый массив array1и так, пройтись до самого конца ващего текущего массива. Когда все элементы будут отсортированы, то всё содержимое из array1 вернуть обратно в array.

Можно всё сделать без второго массива используя несколько if-else

READ ALSO
Laravel websockets

Laravel websockets

Всем привет! Я использую библиотеку https://githubcom/beyondcode/laravel-websockets

244
Миграции в Laravel, как работает метод onDelete()?

Миграции в Laravel, как работает метод onDelete()?

Не могу понять как в миграциях Laravel работает onDelete()Например, такая ситуация

229
Фильтрация файлов из папки в bitrix

Фильтрация файлов из папки в bitrix

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

232