array_chunkで配列をきれいに分割する

array_chunk とは、配列を指定した個数ずつのまとまりに分割し、二次元配列として返す関数です。バッチ処理やページングの下ごしらえで出番の多い関数です。

指定した個数ずつに割る

配列を「n個ずつのまとまり」に分けたいとき、自前でカウンタを回すより array_chunk が素直です。第2引数に一塊のサイズを渡すと、その大きさで切り分けた二次元配列が返ってきます。最後の塊は端数のまま残ります。

$items = range(1, 7);

$chunks = array_chunk($items, 3);
// [[1, 2, 3], [4, 5, 6], [7]]

foreach ($chunks as $group) {
    echo implode(',', $group) . "\n";
}

7要素を3ずつに割ると最後が1個だけになりますが、これはこれで自然な挙動ですね。均等割りを前提にコードを書くと端数で崩れるので、そこだけ気をつけたいところです。

第3引数でキーを保つ

デフォルトでは各塊のキーが0から振り直されます。元のインデックスを残したいときは第3引数 preserve_keystrue にします。連想配列を扱うときはこれがないと元のキーが消えるので、実務では地味に重要だと思います。

$data = ['a' => 1, 'b' => 2, 'c' => 3];

var_dump(array_chunk($data, 2, true));
// [['a' => 1, 'b' => 2], ['c' => 3]]

ページングとバッチ処理での定番

私がよく使うのは、大量レコードをまとめて処理するときの分割です。数万件を一気に INSERT すると重いので、chunk で小分けにしてループする、という形にすると DB もメモリも楽になります。ページング表示の下ごしらえにも使えます。

$records = fetchAllRecords(); // 大量の配列だとする

foreach (array_chunk($records, 500) as $batch) {
    // 500件ずつまとめて処理
    bulkInsert($batch);
}

// ページング: 1ページ10件として3ページ目を取る
$pages = array_chunk($allRows, 10);
$page3 = $pages[2] ?? [];

ただし array_chunk は全件をいったんメモリに載せる前提なので、本当に巨大なデータはジェネレータやカーソルで流したほうが良い場面もあります。あくまで「手元にある配列を割る」道具、という位置づけですね。

まとめ

array_chunk はバッチ処理とページングで出番の多い関数で、preserve_keys の有無で連想配列の扱いが変わる点だけ押さえておけば安心です。端数の塊が出ること、巨大データではメモリに気を配ること、この2つを意識しておくと実務でつまずきにくいと思います。

よくある質問

Q. 割り切れないとどうなりますか?
A. 最後の塊が端数のまま残ります。均等割りを前提にコードを書くと崩れるので、端数が出る想定で処理を書くと安全です。

Q. 連想配列のキーを残したいです。
A. 第3引数 preserve_keystrue にします。既定ではキーが0から振り直されるので、連想配列を扱うときはこれが要ります。

Q. 巨大なデータでも使えますか?
A. array_chunk は全件をいったんメモリに載せる前提です。本当に巨大なデータはジェネレータやカーソルで流すほうが向いています。

類似投稿

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です