配列の分割

配列の分割

あまりないとは思いますが、今の現場で配列を分割してから処理することが必要になりました。
実際に実装したときのメモです。いつか使うかな?

完成イメージ

こんな配列を…。

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

こうしたい 。5個区切りで2分割するイメージです。

[[0, 1, 2, 3, 4],[5, 6, 7, 8, 9]]  

3個区切りの場合はこうですね。最後9が1個だけはみ出て、4分割されます。

[[0, 1, 2],[3, 4, 5],[6 ,7 ,8 ],[9 ]]

使うメソッドのおさらい

map

配列の要素を1つずつ取り出して、関数を実行した後、実行後の配列を返します。

const arr = [1,2,3,4,5];
const result = arr.map(value=>value*2);//[2,4,6,8,10]

slice(start,end)

指定した値を抽出した配列を返します。今回の処理のメインですね。
この処理を繰り返すことで実現します。

[0, 1, 2, 3].slice(0,2) // [0,1]

Math.ceil()

切り上げ。配列の要素数を決める時に使います。

Math.ceil(10/3) //4

スプレッド構文

配列を展開します。使わないやり方もできるけど、今回はこれを使います。

// 要素数5の配列を宣言 ただ、中身がemptyなのでループが回せない
Array(5)

// emptyを展開してundefinedが入る これでループを回せる
[...Array(5)] 

// kenys()は配列内のインデックスキーを配列で返す undefinedが入っているので、[0,1,2,3,4]が出来上がる
[...Array(5).keys()] 

実装

まずは配列を作りましょう

const arr = [...Array(10).keys()]; // 0,1,2,3,4,5,6,7,8,9

次に、区切る数と出来上がる配列の数を指定します。
5個ずつ区切る場合は、最終的に2分割されますね。

const sliceNum = 5;
const sliceSize = Math.ceil(arr.length/sliceNum); // 2

最終的に2個(sliceSize)の配列を作りたい。
mapで色々記述するとして、とりあえず2個の配列を作ることだけ…。

const sliceArray = [...Array(sliceSize).keys()].map((index)=>{
    return index;
})//[0,1]

後はメインの処理。sliceをこんな感じで使えば目的通りの配列ができそう。

arr.slice(0,5) // [0,1,2,3,4]
arr.slice(5,10) // [5,6,7,8,9]

といっても、絶対値で指定することはできません。
sliceNumで5個ずつ区切るってことは定義してるので、
sliceとsliceNumを組み合わせるとこんな感じですね。

arr.slice(0*sliceNum , 1 * sliceNum)  // [0,1,2,3,4]
arr.slice(1*sliceNum , 2 * sliceNum)  // [5,6,7,8,9]

mapの中でindexが0,1と渡ってくるので、それを更にそれを組み合わせることで、分割した配列の出来上がり!

const sliceArray = [...Array(sliceSize).keys()].map((index)=>{
    return arr.slice(index*sliceNum , (index+1) * sliceNum);
})//[0,1,2,3,4],[5,6,7,8,9]

ってことでまとめるとこんな感じ。
mapも一行なので省略できますね。せっかくなので関数にします。

const createSliceArray = (arr,sliceNum) => {
    const sliceSize = Math.ceil(arr.length/sliceNum); 
    return [...Array(sliceSize).keys()].map(index=>arr.slice(index*sliceNum , (index+1) * sliceNum));
}
const arr = [...Array(10).keys()];
const sliceNum = 5;
const sliceArray = createSliceArray(arr,sliceNum);

//[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]

いいですねー。
sliceNumを3にすると、[[0, 1, 2],[3, 4, 5],[6, 7, 8],[9 ]]が出来上がります。いつかまた使う日が来るかも。