Panda Noir

JavaScript の限界を究めるブログでした。最近はいろんな分野を幅広めに書いてます。

どんな深さの配列も1次元配列にする

ES2019でArray#flatMapが導入されたので、それを使ってどんな深さの配列でも1次元にする方法を紹介します。

flatMapの仕様

flatMapはmap()してからflat()するメソッドです。

[1,2,3].map(n => [n,-n]); // [[1,-1],[2,-2],[3,-3]]
[[1,-1],[2,-2],[3,-3]].flat();  // [1,-1,2,-2,3,-3]

[1,2,3].flatMap(n => [n,-n]); // [1,-1,2,-2,3,-3]

flatMapを使って1次元にする

コード

flatMapを使って、どんな深さの配列でも1次元に落とし込みます。これは「無限回flat()を行い、1次元になった時点でやめる」のと等価なので、flatInfと名付けました。

const arr = [1, [2, [3, 4, [5]]]];

const flatInf = item => {
    if (Array.isArray(item))
        return item.flatMap(flatInf);
    return item;
};

console.log(flatInf(arr)); // [1, 2, 3, 4, 5]

flatInfの動作

  1. 配列の各要素を「1次元の配列あるいは要素」にする
  2. できた配列をflat()する

これだけです。配列の要素が1次元の配列か要素のみなら、flat()するだけで1次元になります。

// 1次元の配列か要素のみの配列
[[1, 2], 3, [4, 5, 6], 7, 8, 9].flat(); // [1, 2, 3, 4, 5, 6, 7, 8, 9]

与えられる配列の各要素の深さは1次元とは限りません。コレを1次元にするために、再帰的にflatInfを適用しています。

おまけ: コードを圧縮する

そこまで変わりませんが。

const arr = [1, [2, [3, 4, [5]]]];

const flatInf=a=>Array.isArray(a)?a.flatMap(flatInf):a;

console.log(flatInf(arr)); // [1, 2, 3, 4, 5]