chunk
Lodashとかであるやつです。
第1引数の配列を第2引数の数の要素数の配列に分割します。
const chunk = (array, n) =>
array.reduce(
(a, c, i) =>
i % n == 0 ? [...a, [c]] : [...a.slice(0, -1), [...a[a.length - 1], c]],
[]
);
実行結果はこんな感じ
const array = Array.from({ length: 7 }, (v, k) => k);
chunk(array, 2);
// [ [ 0, 1 ], [ 2, 3 ], [ 4, 5 ], [ 6 ] ]
divide
自分が欲しかったやつはこれでした。
第1引数の配列を第2引数の数の配列に分割します。
const divide = (array, n) => {
const tbl = new Array(n);
for (let y = 0; y < n; y++) {
tbl[y] = new Array();
}
array.forEach((a, i) => {
tbl[(i + 1) % n].push(a);
});
return tbl;
};
決められたスレッドを利用して並列化したかったのでこんなのが必要になりました。
実行結果はこんな感じ
const array = Array.from({ length: 7 }, (v, k) => k);
divide(array, 2);
// [ [ 1, 3, 5 ], [ 0, 2, 4, 6 ] ]
ぐぐってもchunk
みたいな処理しかでてこなかった。もっといい書き方ありそう。
追記
コメントにて @ttatsf さんからイカしたコードをいただきました!かっこいい...!
const chunk = n => xs =>
xs.reduce(
(acc, _, i) =>
i % n === 0 ? [ ...acc, xs.slice( i, i + n ) ]
: [...acc]
, []
)
const divide = n => xs =>
zipLongest( chunk( n )( xs ) )
const zipLongest = xs =>
xs.reduce( zipLonger, [])
const zipLonger = (xs, ys) =>
xs.length >= ys.length ? xs.map(
(e, i) => i >= ys.length ? [e].flat() : [ e, ys[i] ].flat()
)
: ys.map(
(e, i) => i >= xs.length ? [e].flat() : [ xs[i], e ].flat()
)
//使用例:
const n = 2
const xs = [ 0, 1, 2, 3, 4, 5, 6 ]
chunk( n )( xs ) // [ [ 0, 1 ], [ 2, 3 ], [ 4, 5 ], [ 6 ] ]
divide( n )( xs ) // [ [ 0, 2, 4, 6 ], [ 1, 3, 5 ] ]