reduce
just [recursively] combines a data structure into a new value: that value can be anything.
So for example, reimplementing some of the JS array methods (and adding some other common ones):
The normal example, using it to take an array of numbers and sum them, returning a single value: sum([1,2,3,4])
returns 10
function sum(arr) {
return reduce((a,b) => a + b, 0);
}
reverse
returns a reversed version of the input array (non-mutating version of Array.prototype.reverse
). So reverse([1,2,3,4])
returns [4,3,2,1]
.
function reverse(arr) {
return arr.reduce((acc, v) => [v, ... acc], []);
}
Do the same as Array.prototype.map
- so map([1,2,3,4], (x) => x ** 2)
returns [1,4,9,16]
.
function map(arr, fn) {
return arr.reduce((acc, v) => {
return acc.concat(fn(v));
}, []);
}
Flattens an array of arrays to a single array, same as Array.prototype.flat
- so flatten([[1],[2],[3],[4]])
returns [1,2,3,4]
.
function flatten(arr) {
return reduce((acc, arr) => [...acc, ...arr], [])
}
That only works for one level of nesting, so could take an array of arrays of any depth and flatten to one array: so flattenDeep([1,[2,[3,4]]])
returns [1,2,3,4]
.
function flattenDeep(arr) {
return arr.reduce((acc, v) => {
if (Array.isArray(v)) {
return acc.concat(flatten(v));
} else {
return acc.concat(v);
}
}, []);
}
Joins an array into a string with a given joining string - same as Array.prototype.join
, so join([1,2,3,4], ' ')
returns '1 2 3 4'
.
function join(arr, joiner = ',') {
return arr.reduce((acc, v, index) => {
if (index == 0) {
return `${v}`
} else {
return `${acc}${joiner}${v}`;
}
}, '');
}
Given an array, returns an array with an item inserted between each of the original values, so intersperse([1,2,3,4], 'hi')
returns[1, 'hi', 2, 'hi', 3, 'hi', 4]
.
function intersperse(arr, item) {
return arr.reduce((acc, v, index) => {
if (index == 0) {
return [v]
} else {
return acc.concat([item, v]);
}
}, []);
}
Filter and map on the same array, first function you pass is the filter, then anything that gets through that gets mapped - so filterMap([1,2,3,4], (x) => x % 2 === 0, (x) => x ** 2)
returns [4, 16]
function filterMap(arr, filter, mapper) {
return arr.reduce((acc, v) => {
if (filter(v)) {
return acc.concat(mapper(v));
} else {
return acc;
}
}, []);
}