8
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JavaScriptで長い配列を長さnの小さい配列に分割するワンライナー

Last updated at Posted at 2024-04-09

やりたいこと

例えば長さ12の配列を、

変換前
const src = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']

このように、

変換前
[
  ['Jan', 'Feb', 'Mar'], 
  ['Apr', 'May', 'Jun'], 
  ['Jul', 'Aug', 'Sep'], 
  ['Oct', 'Nov', 'Dec']
]

長さ3など短い複数の配列に分割したいとします。これを実現するワンライナーを紹介します。

答え(ワンライナー)

答え
const dst = Array(Math.ceil(src.length/n)).fill().map((_, i) => src.slice(n*i, n*(i+1)));
  • まず、Math.ceil(src.length/n)で分割数を求めます。例えば、長さ12を長さ3で分けるならちょうど4ですが、繰り上げが入るので長さ12を長さで5で分けた場合は2でなく3が導かれます。
  • Array(分割数).fill()fill()を呼んでいるのは、単に配列を初期化しただけだとインデックス(オブジェクトのキー)がなく次に説明するmap()が無効となってしまうためです。
  • map()でループします。インデックスiが取る値は0から分割数-1までとなります。
  • slice()で元の配列から部分配列を切り取ります。slice(start, end)endend >= src.length の場合でもsrc.lengthが使用され、nで割り切れないケースでも安全です。

実行例

サンプルコード

arrsplit.js
process.stdin.resume();
process.stdin.setEncoding("utf8");

const lines = [];
const reader = require("readline").createInterface({
    input: process.stdin,
    output: process.stdout
});
reader.on("line", (line) => {
    lines.push(line);
});
reader.on("close", () => {
    // Change left-hand side dependent on input
    const [n, ...src] = lines.map(e => e.split(/[,\s]/).filter(e => e != "")).flat().map(e => isFinite(e) ? +e : e);
    const dst = Array(Math.ceil(src.length/n)).fill().map((_, i) => src.slice(n*i, n*(i+1)));
    console.log(dst);
});

実行例1 (nで割り切れるとき)

$ node arrsplit.js
3
Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec
(press Ctrl+d)
[
  [ 'Jan', 'Feb', 'Mar' ],
  [ 'Apr', 'May', 'Jun' ],
  [ 'Jul', 'Aug', 'Sep' ],
  [ 'Oct', 'Nov', 'Dec' ]
]

実行例2 (nで割り切れないとき)

$ node arrsplit.js
5
Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec
(press Ctrl+d)
[
  [ 'Jan', 'Feb', 'Mar', 'Apr', 'May' ],
  [ 'Jun', 'Jul', 'Aug', 'Sep', 'Oct' ],
  [ 'Nov', 'Dec' ]
]

所感

他にも余りがあるか判定を挟む方法や、reduce()を使った方法など様々ありますが、上記が個人的には直感的で覚えやすく、かつ簡潔なのでバランスが良いと思っております。
オンラインのコーディング問題を解くときなどに、JavaScriptで標準入力から数値や文字列を一発で受け取る #JavaScript - Qiita と組み合わせて使っていただくと便利ではないかと思います。

参考

8
6
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?