Increase performance for partitionBy

This commit is contained in:
Angelos Chalaris
2020-05-20 19:00:29 +03:00
parent 53e12d2241
commit 1f25d57f60

View File

@ -1,34 +1,28 @@
--- ---
title: partitionBy title: partitionBy
tags: array,object,function,intermediate tags: array,object,function,advanced
--- ---
Applies `fn` to each value in `arr`, splitting it each time `fn` returns a new value. Applies `fn` to each value in `arr`, splitting it each time `fn` returns a new value.
Use `Array.prototype.reduce()` and `Array.prototype.push()` to create the start index of each partition. Use `Array.prototype.reduce()` with an accumulator object that will hold the resulting array and the last value returned from `fn`.
Use `Array.prototype.map()` to create the slice interval of each partition. Use `Array.prototype.push()` to add each value in `arr` to the appropriate partition in the accumulator array.
Use `Array.prototype.slice()` to create each partition.
```js ```js
const partitionBy = (arr, fn) => const partitionBy = (arr, fn) =>
arr arr.reduce(
.reduce((acc, val, i, a) => { ({ res, last }, v, i, a) => {
acc.push(fn(val, i, a)); const next = fn(v, i, a);
return acc; if (next !== last) res.push([v]);
}, []) else res[res.length - 1].push(v);
.reduce((acc, val, i, a) => { return { res, last: next };
if (val !== a[i + 1]) { },
acc.push(i + 1); { res: [] }
} ).res;
return acc;
}, [])
.map((interval, i, a) =>
i === 0 ? arr.slice(...[0, interval]) : arr.slice(...[a[i - 1], interval])
);
``` ```
```js ```js
const numbers = [1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 4, 5, 5, 5, 5, 5]; const numbers = [1, 1, 3, 3, 4, 5, 5, 5];
partitionBy(numbers, n => n % 2 === 0); // = > [ [ 1, 1, 1, 1, 1, 3, 3, 3, 3, 3 ], [ 4 ], [ 5, 5, 5, 5, 5 ] ] partitionBy(numbers, n => n % 2 === 0); // [[1, 1, 3, 3], [4], [5, 5, 5]]
partitionBy(numbers, n => n); // => [ [ 1, 1, 1, 1, 1 ], [ 3, 3, 3, 3, 3 ], [ 4 ], [ 5, 5, 5, 5, 5 ] ] partitionBy(numbers, n => n); // [[1, 1], [3, 3], [4], [5, 5, 5]]
``` ```