I have read this article, but I don't seem to understand JavaScript's reduce syntax correctly. How can I pass additional parameters to custom reducer function?
Calling reducer function.
data = Object.values(data.reduce(reducer, {}));
Reducer function example.
const reducer = (acc, cur) => {
if (somethingIsTrue) {
return acc;
}
};
Right now it is working like it should, but let's say that I'm calling reducer function and I want to pass simple variable that contains "Hello World" in away that function doesn't see it as an argument. How can I achieve this?
CodePudding user response:
It looks like you want to group data by using an value (this could be a function, too) for the grouping.
For example, get all values separated by even an odd values.
First, you need a function which returns a flag to separate the values, like
v => v % 2 // even -> 0, odd -> 1
then take a reducer function, like
(acc, value) => {
// fn is not defined here, but it works a grouping function
// the following line reads:
// if acc[fn(value)] is undefined or null assign an empty array
// then push a value
(acc[fn(value)] ??= []).push(value);
return acc;
}
now you need to combine both function by adding a closure over fn
at the start of the parameters:
fn => (acc, value) => {
// rest is the same
finally call the function
const
evenOrOdd = v => v % 2,
reducer = fn => (acc, value) => {
(acc[fn(value)] ??= []).push(value);
return acc;
},
data = [2, 7, 9, 4, 3, 5, 1],
result = Object.values(data.reduce(
reducer(evenOrOdd),
{}
));
console.log(result);
CodePudding user response:
You can do function composition to "build up" something called an higher order function. Basically the idea is to create a function that returns a "child function", which will have access to the parent function's variables.
// Parent function (getReducer)
function getReducer(stringToAppend) {
// Child function (reducer)
function reducer(acc, curr) {
// Child function has access to parent's variables (in this case stringToAppend)
acc[curr] = stringToAppend curr
return acc
}
return reducer
}
const data = [0,1,2,3,4,5,6,7,8,9]
const result = data.reduce(getReducer("Hello World "), {})
console.log('result :>> ', result);
In console:
result :>> {
'0': 'Hello World 0',
'1': 'Hello World 1',
'2': 'Hello World 2',
'3': 'Hello World 3',
'4': 'Hello World 4',
'5': 'Hello World 5',
'6': 'Hello World 6',
'7': 'Hello World 7',
'8': 'Hello World 8',
'9': 'Hello World 9'
}
I used the function
syntax as I found it more verbose and explicit for explaining this. You could of course arrow functions. Using arrow syntax the function could look as simple as:
function getReducer (stringToAppend) {
return (acc, curr) => {
acc[curr] = stringToAppend curr
return acc
}
}