はじめに
ある案件の処理上、一次元配列を指定の要素数ごとに分割し、二次元配列にする必要があったため、そのロジックに関する小ネタです。即時関数、アロー関数式、通常関数(関数宣言)の3タイプのご紹介です。(備忘録扱いです)
補足
本記事執筆当初はArray.reduceを用いたロジックを紹介していましたが、コメントでご指摘いただいた内容より、Array.flatMapを用いた内容に修正いたしました。これに伴いタイトルも一部修正いたしました。
ロジック
flatMap.js
const originalArr = [1,2,3,4,5,6,7,8,9,10,11,12,13];
const num = 3; // 分割単位
// 即時関数
const chunkedArr = ((arr, size) => arr.flatMap((_, i, a) => i % size ? [] : [a.slice(i, i + size)]))(originalArr, num);
// console.log(chunkedArr); -> [[1,2,3],[4,5,6],[7,8,9],[10,11,12],[13]]
// アロー関数式
const hoge = (arr, size) => arr.flatMap((_, i, a) => i % size ? [] : [a.slice(i, i + size)]);
// console.log(hoge(originalArr, num)); -> [[1,2,3],[4,5,6],[7,8,9],[10,11,12],[13]]
// 通常関数(関数宣言)
function fuga(arr, size){
return arr.flatMap((_, i, a) => i % size ? [] : [arr.slice(i, i + size)]);
}
// console.log(fuga(originalArr, num)); -> [[1,2,3],[4,5,6],[7,8,9],[10,11,12],[13]]
Array.reduceを用いた方法
本記事自体備忘録扱いのため、執筆当時のオリジナルのロジックも残しておきます。以下を用いる場合、コメントでもご指摘いただいていますように初期配列の設定や作業用のコピーが発生するため、その分効率的とはいえません。Array.reduce
を用いるならば、@tkturboさんのロジックを参考にしましょう。(丸投げ!)
reduce.js
// 即時関数
const chunkedArr = ((arr, size) => arr.reduce((previous, _, i) => i % size ? previous : [...previous, arr.slice(i, i + size)], []))(originalArr, num);
// console.log(chunkedArr); -> [[1,2,3],[4,5,6],[7,8,9],[10,11,12],[13]]
// アロー関数式
const hoge = (arr, size) => arr.reduce((previous, _, i) => i % size ? previous : [...previous, arr.slice(i, i + size)], []);
// console.log(hoge(originalArr, num)); -> [[1,2,3],[4,5,6],[7,8,9],[10,11,12],[13]]
// 通常関数(関数宣言)
function fuga(arr, size){
return arr.reduce((previous, _, i) => i % size ? previous : [...previous, arr.slice(i, i + size)], []);
}
// console.log(fuga(originalArr, num)); -> [[1,2,3],[4,5,6],[7,8,9],[10,11,12],[13]]
コーディングスタイルは人それぞれですので、案件内容や前後の処理との関係など、必要な場面に応じて使い分ければいいと思います。
最後に
紹介したロジックが必ずしも最適解ということではございません。誰かの役に立てば幸いです。
@nagtkk様をはじめ、コメントいただいた皆様に感謝いたします。