Array.flat
ES2019で配列に追加された新しい関数にflat
があります。
これは、ネストした階層をほぐして平らにする関数です。
const nested = [[1,2],3,4];
const flattend = nested.flat();// [1,2,3,4]
基本は上記の使い方ですが、引数で何階層まで平らにするも指定できます。
詳しい使い方はMDNに詳しいのでそちらで。
ただ、複数階層flatはちょっと使いどころが思いつきません。
使いどころ
始めに見たときはflatMapはともかく、これはあまり使いどころないんじゃ?
と思ったのですが、Promise.allをごりごり使うような処理を書く時は意外と便利でした。
Promise.allで取ってきた配列を結合したい場合
非同期処理で同じ型の配列を同時に複数取りたい時がたまにあります。
(複数のIDに紐づく子要素のリストを取りたい場合とか)
そういう場合、
Promise.all(ids.map(mapToPromiseFunction)).then(results => {
});
という感じにありますが、resultsは欲しい要素の配列の配列になってしまいます。
各IDについて別個に扱いたい場合はそれでOKですが、まとめて扱いたい場合はresultsに入っている各配列を結合してやる必要があります。
そんな時、今までは
const concatenated = results.reduce((prev,current) => prev.concat(current));
と書く必要がありましたが、flatを使えば
const flattend = results.flat();
と書けます。
コード量が少なくて済みますし、より宣言的で何をやっているのか一目瞭然です。
こいつはいい。
注意点
ただ、このflat、Typescriptの対応がまだまだ甘い部分があります。
基本的に、中身の階層がずれていたり、適切な階層数を指定していないとすぐにany []型になります。
[[1,2],[3,4]].flat();//number []
[1,2,[3,4]].flat();// any []
[[[1,2]],[[3,4]]].flat(2);//number []
[[[1,2]],[[3,4]]].flat(3);//any []
[1,2,[3,4].flat()].flat();//any []
入れ子もダメなので、Typescriptを使う場合は一階層に留めておいた方がよさそう。
まとめ
- flatでいい感じに配列が結合できる
- Promise.all辺りと組み合わせると便利
- 複数階層の平坦化なども出来るが、Typscript対応が甘いので注意