---
type: how-to
language: javascript
slug: array/chunk
title: "配列を決まった数ずつに分ける"
title_tag: "JavaScript 配列を分割する — chunk を自作する方法"
summary: >
  slice() を繰り返して塊にします。端数の扱い、空配列のとき、要素数より大きい数を渡したとき、
  そして 0 を渡すと止まらなくなる理由まで、実行して確かめます。
description: >
  slice を繰り返すだけで作れます。端数や空配列は自然に処理されますが、size に 0 を渡すと
  無限ループになります。防ぎ方と、まとめて処理する実務での使い方まで示します。
status: published
difficulty: 2
minutes: 7

versions:
  verified: "Node 22.22.3"
  since: "ES5"
  deprecated: null
  removed: null

sources:
  - title: "Array.prototype.slice — ECMAScript® 2026 Language Specification"
    url: "https://tc39.es/ecma262/#sec-array.prototype.slice"
  - title: "Array.from — ECMAScript® 2026 Language Specification"
    url: "https://tc39.es/ecma262/#sec-array.from"

terms: [分割, 端数, 無限ループ]

links:
  related:
    - javascript/reference/array/slice
    - javascript/how-to/async/parallel
    - javascript/reference/array/map

content_updated_at: 2026-09-08
published_at: 2026-09-08
---

## 答え

`slice()` を繰り返します。

```js run
function chunk(list, size) {
  const out = [];

  for (let i = 0; i < list.length; i += size) {
    out.push(list.slice(i, i + size));
  }

  return out;
}

console.log(chunk([1, 2, 3, 4, 5], 2));
```
```output
[ [ 1, 2 ], [ 3, 4 ], [ 5 ] ]
```

**標準のメソッドはありません。** これだけで足ります。

## 端は自然に処理される

```js run
function chunk(list, size) {
  const out = [];

  for (let i = 0; i < list.length; i += size) {
    out.push(list.slice(i, i + size));
  }

  return out;
}

console.log(chunk([1, 2, 3], 5));
console.log(chunk([], 2));
console.log(chunk([1, 2, 3], 1));
```
```output
[ [ 1, 2, 3 ] ]
[]
[ [ 1 ], [ 2 ], [ 3 ] ]
```

- 要素数より大きい数を渡すと、**塊は1つ**
- 空配列なら**空配列**（`[[]]` にはならない）
- `1` を渡すと、1個ずつの塊

`slice()` は範囲を超えても落ちないので、[key:割り切れないときの場合分けが要りません]。
→ [slice() と splice()](/ja/javascript/reference/array/slice/)

## `Array.from()` で書く

先に個数を決めてから作る書き方もあります。

```js run
function chunk(list, size) {
  return Array.from({ length: Math.ceil(list.length / size) }, (_, i) =>
    list.slice(i * size, i * size + size));
}

console.log(chunk([1, 2, 3, 4, 5], 2));
console.log(Math.ceil(5 / 2));
```
```output
[ [ 1, 2 ], [ 3, 4 ], [ 5 ] ]
3
```

`Math.ceil()` で[key:切り上げる]のが要点です。`5 / 2` は `2.5` なので、塊は[num:3]つ。

**どちらでも構いません。** `for` のほうが読み手を選ばないので、迷ったらそちらで。

## 気をつけること：`0` を渡すと止まらない

```js bad
for (let i = 0; i < list.length; i += 0) {
  // i がずっと 0 のまま。永久に終わらない
}
```

`size` に `0` が入ると `i` が進まず、**無限ループになります。**

[bad:このページでは実行できません。] 止まらないコードは実行の枠を使い切ってしまいます。

`size` が変数から来るなら、**先に確かめてください。**

```js run
function chunk(list, size) {
  if (!Number.isInteger(size) || size < 1) {
    throw new RangeError('size は 1 以上の整数にしてください');
  }

  const out = [];

  for (let i = 0; i < list.length; i += size) {
    out.push(list.slice(i, i + size));
  }

  return out;
}

console.log(chunk([1, 2, 3], 2));

try {
  chunk([1, 2, 3], 0);
} catch (error) {
  console.log(error.name + ': ' + error.message);
}
```
```output
[ [ 1, 2 ], [ 3 ] ]
RangeError: size は 1 以上の整数にしてください
```

**外から来る値は、使う前に確かめる。** これは分割に限りません。

## 文字列にも使える

`slice()` は文字列にもあるので、同じ関数がそのまま動きます。

```js run
function chunk(list, size) {
  const out = [];

  for (let i = 0; i < list.length; i += size) {
    out.push(list.slice(i, i + size));
  }

  return out;
}

console.log(chunk('abcdef', 2));
```
```output
[ 'ab', 'cd', 'ef' ]
```

[bad:ただし絵文字は途中で割れます。] 文字として分けたいなら、
先に `[...text]` で配列にしてから渡してください。
→ [文字を正しく数える](/ja/javascript/learn/string/unicode/)

## 中身は複製されない

```js run
function chunk(list, size) {
  const out = [];

  for (let i = 0; i < list.length; i += size) {
    out.push(list.slice(i, i + size));
  }

  return out;
}

const rows = [{ id: 1 }, { id: 2 }, { id: 3 }];
const pages = chunk(rows, 2);

pages[0][0].id = 99;

console.log(rows[0].id);
console.log(pages.length, pages.flat().length);
```
```output
99
2 3
```

`slice()` は[type:浅いコピー]なので、**塊の中身は元と同じオブジェクト**です。
分けただけで安全になったわけではありません。

## よくある間違い

### 進める幅を間違える

```js bad
function wrong(list, size) {
  const out = [];

  for (let i = 0; i < list.length; i++) {
    out.push(list.slice(i, i + size));
  }

  return out;
}

console.log(wrong([1, 2, 3, 4], 2));
```
```output
[ [ 1, 2 ], [ 2, 3 ], [ 3, 4 ], [ 4 ] ]
```

`i++` にすると[bad:1つずつずれた窓]になり、要素が重複します。
**進める幅は `size` です。**

[dim:ちなみに、この「1つずつずらした窓」が欲しい場面もあります（移動平均など）。そのときは意図してこう書きます。]

## 何に使うか

いちばん多いのは、**まとめて処理する数を抑える**ときです。

```js run
async function load(n) {
  return n * 10;
}

const ids = [1, 2, 3, 4, 5];
const out = [];

for (let i = 0; i < ids.length; i += 2) {
  const part = ids.slice(i, i + 2);

  console.log('この回:', part);
  out.push(...await Promise.all(part.map(load)));
}

console.log(out);
```
```output
この回: [ 1, 2 ]
この回: [ 3, 4 ]
この回: [ 5 ]
[ 10, 20, 30, 40, 50 ]
```

**塊の中は同時、塊どうしは順番**になります。
1000件を一度に投げて断られる、という事故を防げます。
→ [複数の非同期処理を同時に走らせる](/ja/javascript/how-to/async/parallel/)

表示を何行かごとに区切る、まとめて登録する、といった用途にも同じ形が使えます。

## 何番目の塊かを一緒に持つ

表示するときは、塊の番号が要ることが多くあります。

```js run
function chunk(list, size) {
  const out = [];

  for (let i = 0; i < list.length; i += size) {
    out.push(list.slice(i, i + size));
  }

  return out;
}

const rows = ['あ', 'い', 'う', 'え', 'お'];

chunk(rows, 2).forEach((page, i) => {
  console.log(`${i + 1}ページ目: ${page.join(', ')}`);
});
```
```output
1ページ目: あ, い
2ページ目: う, え
3ページ目: お
```

`forEach()` の第2引数が[key:何番目か]です。
→ [配列を繰り返す](/ja/javascript/learn/array/loop/)

## 逆に、平らに戻す

`flat()` で1段だけ戻せます。

```js run
const pages = [[1, 2], [3, 4], [5]];

console.log(pages.flat());
console.log(pages.flat().length);
```
```output
[ 1, 2, 3, 4, 5 ]
5
```

**分けて、処理して、戻す**という形がそのまま書けます。
→ [入れ子の配列を平らにする](/ja/javascript/how-to/array/flatten/)

## まとめ

- `slice()` を `size` ずつずらすだけ。**標準のメソッドは無い**
- 端数・空配列・大きすぎる `size` は[em:自然に処理される]。場合分けは要らない
- **`size` に `0` を渡すと止まらない。** 外から来るなら先に確かめる
- 同時に走らせる数を抑えるのが、いちばん多い使い道
