LoginSignup
1
0

More than 3 years have passed since last update.

Arrayの分割2種

Last updated at Posted at 2019-12-08

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 ] ]
1
0
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0