массивы — перемещение элементов с использованием array_chunk с переполнением стека

У меня есть базовый массив, в котором я использую array_chunk, чтобы разделить его на 3 элемента.

$array = array(
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'
);

$chunk = array_chunk($array, 3);

Результат выглядит следующим образом

[
[
"a",
"b",
"c"],
[
"d",
"e",
"f"],
[
"g",
"h"]
]

(Лас чанк имеет 2 элемента)

Если последний «чанк» имеет только 2 элемента, как я могу переместить элемент первого чанка вниз, чтобы у первого элемента было 2?

Это должно выглядеть так:

[
[
"a",
"b",
],
[
"c""d",
"e",
],
[
"f""g",
"h
]
]

(Первый кусок имеет 2 элемента)

2

Решение

Самым простым способом является многократное выполнение erray_reverse: сначала инвертировать весь массив, затем разделить, затем инвертировать каждый фрагмент, а затем, наконец, массив фрагментов.

Как однострочник, это выглядит так: $chunk = array_reverse(array_map('array_reverse', array_chunk(array_reverse($array), 3)));

Имейте в виду, однако, что обращение к массиву является дорогостоящей операцией, поэтому, если ваш массив является более точным, чем в вашем примере, это не рекомендуется.


Более эффективный, но также и больше кода:
Рассчитать количество элементов, которые должны быть в первом чанке, по модулю:
$first_chunk_size = count($array) % 3;

Далее, чтобы избежать пустого массива, если размер массива кратен размеру куска, исправьте размер куска, если по модулю выдает 0:
$first_chunk_size = $first_chunk_size == 0 ? 3 : $first_chunk_size;

затем отрезаем первую часть:
$first_chunk = array_slice($array, 0, $first_chunk_size);

Затем разделите остальную часть массива:
$chunks = array_chunk(array_slice($array,$first_chunk_size),3);

затем объедините первый блок и другие блоки в один массив:
array_unshift($chunks, $first_chunk);

Полный код второго подхода:

$array = [
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'
];

$first_chunk_size = count($array) % 3;
$first_chunk_size = $first_chunk_size == 0 ? 3 : $first_chunk_size;

$first_chunk = array_slice($array, 0, $first_chunk_size);
$chunks = array_chunk(array_slice($array,$first_chunk_size),3);
array_unshift($chunks, $first_chunk);

var_dump($chunks);

(очевидно, этот код можно упростить, если не делать все шаг за шагом)


РЕДАКТИРОВАТЬ: Прочитав ваши комментарии к другим ответам, вы можете немного изменить этот подход и превратить его в функцию повторного получения. С некоторой очисткой кода. это может выглядеть так:

$array = [
'a', 'b', 'c', 'd', 'e', 'f', 'g'
];

function custom_array_chunk ($array) {
$first_chunk_size = count($array) % 3;
if ($first_chunk_size == 0) {
$chunks = array_chunk($array, 3);
} else {
$chunks = custom_array_chunk(array_slice($array,2));
array_unshift($chunks, array_slice($array, 0, 2));
}
return $chunks;
}

var_dump(custom_array_chunk($array));

Это будет работать для обоих случаев, 1 и 2 элемента «осталось» и даст именно то, что вы сказали нам.

демонстрация

2

Другие решения

Вы можете сначала перевернуть массив, используя array_reverse, затем используйте array_chunk. Затем переверните внутренние массивы и снова переверните внешние массивы:

$array = array(
'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h'
);
$array = array_reverse($array);
$chunk = array_chunk($array, 3);
$array = array_map('array_reverse', $chunk);
print_r(array_reverse($array));

демонстрация

Результат

Array
(
[0] => Array
(
[0] => a
[1] => b
)

[1] => Array
(
[0] => c
[1] => d
[2] => e
)

[2] => Array
(
[0] => f
[1] => g
[2] => h
)

)
1

Функционально подход множественного array_reverse вполне понятен:

$chunk = array_reverse(array_map('array_reverse', array_chunk(array_reverse($array), 3)));

Тем не менее, это довольно дорого, особенно для больших массивов. Другой способ — вырезать элементы из конца массива и добавить их к массиву chunked:

$size = 3;
$chunk = array();
while (count($array) > 0) {
array_unshift($chunk, array_slice($array, -$size));
$array = array_slice($array, 0, -$size);
}

Это работает примерно в 20 раз быстрее (более 100 тыс. Итераций) для вашего массива и примерно в 1000 раз быстрее для массива, содержащего более 600 элементов.

1

Вы можете добавить пустые данные к вашему массиву, в виде array_chunk, который будет соответствовать вашим потребностям.

Затем удалите эти предварительно подготовленные данные.

$chunk = 3;
$nbToPrepend = ($chunk - count($array) % $chunk);
$prepend = array_fill(0, $nbToPrepend, null);
$result = array_chunk(array_merge($prepend, $array), $chunk);
$result[0] = array_slice($result[0], $nbToPrepend);
0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector