Разгруппировать элементы массива на основе функции

const unzip = arr =>
  arr.reduce(
    (acc, val) => (val.forEach((v, i) => acc[i].push(v)), acc),
    Array.from({
      length: Math.max(…arr.map(x => x.length))
    }).map(x => [])
  );
const zipWith = (…array) => {
  const fn =
    typeof array[array.length - 1] === 'function' ? array.pop() : undefined;
  return Array.from({ length: Math.max(…array.map(a => a.length)) }, (_, i) =>
    fn ? fn(…array.map(a => a[i])) : array.map(a => a[i])
  );
};
const unzipWith = (arr, fn) =>
  arr
    .reduce(
      (acc, val) => (val.forEach((v, i) => acc[i].push(v)), acc),
      Array.from({
        length: Math.max(…arr.map(x => x.length))
      }).map(x => [])
    )
    .map(val => fn(…val));
unzip([['a', 1, true], ['b', 2, false]]); // [['a', 'b'], [1, 2], [true, false]]
unzip([['a', 1, true], ['b', 2]]); // [['a', 'b'], [1, 2], [true]]
zipWith([1, 2], [10, 20], [100, 200], (a, b, c) => a + b + c); // [111, 222]
zipWith(
  [1, 2, 3],
  [10, 20],
  [100, 200],
  (a, b, c) =>
    (a != null ? a : 'a') + (b != null ? b : 'b') + (c != null ? c : 'c')
); // [111, 222, '3bc']
unzipWith(
  [
    [1, 10, 100],
    [2, 20, 200],
  ],
  (…args) => args.reduce((acc, v) => acc + v, 0)
);
// [3, 30, 300]
Массивы и объекты JavaScript JavaScript