概要
JavaScript で配列を任意のグループに分ける。
例えば 7 人を 3 グループに分けると 3人-2人-2人みたいに分けたい。
考え方
- 「配列」と「分けたい数」を引数で受け取る
- まず割り切れる分を分けてしまう
- 余りを改めて配る
要素数が 7 だと 7 / 3 = 2 余り 1
になる。
まず 2-2-2
に分けたあと、余った分を先頭に追加して 3-2-2
にする。
実装
const splitArray = (array, splitSize) => {
const itemCount = Math.floor(array.length / splitSize)
const splited = []
for (let i = 0; i < splitSize; i++) {
if (i === 0) {
splited.push(array.slice(i, itemCount ));
continue
}
splited.push(array.slice(itemCount * i, (itemCount * (i + 1))));
}
const fraction = array.length % splitSize
if (fraction === 0) {
return splited
}
for (let i = 0; i < fraction; i++) {
(splited[i]).push(array[array.length - (fraction-i)])
}
return splited
}
テスト
たとえば jest で書くなら。
test('7人を3つのグループに分ける', () => {
const array = [1, 2, 3, 4, 5, 6, 7]
const splitSize = 3
expect(splitArray(array, splitSize)).toMatchObject([
[1, 2, 7],
[3, 4],
[5, 6]
])
})
問題点
このやり方だと余りをあとから配るので、先頭のグループが [1, 2, 7]
になってしまう。
これを [1, 2, 3]
にするとしたら、どうするか。
- 一度要素を総なめして、グループ分けをマークする
- マークに沿って要素を詰め直す
こっちの方がよさそうな気がした。
もっとスマートなやり方もある気がする。