Reputation:
I'm trying to create a currying function returning the list of parameters but I don't how to make it. This is my code :
const getParameters = arg => {
const parameters = [];
const innerFunction = arg => {
parameters.push(arg);
return innerFunction;
};
return innerFunction(arg);
};
getParameters(1)(2)(5); // => expected value [1,2,5]
getParameters(1)(2)(5)(20); // => expected value [1,2,5,20]
Upvotes: 0
Views: 409
Reputation: 2036
As we all know world of JavaScript
is a magic world, and even this thing, like infinite currying is possible
const nice = (...args) => {
return Object.assign(
nice.bind(0, ...args),
{ valueOf: () => args.reduce((a, b) => a + b, 0) }
)
}
console.log(+nice(1)()(2)) // ~> 3
console.log(+nice(1, 2)()(3)()()) // ~> 6
console.log(+nice()()()()()()(1)) // ~> 1
console.log(+nice()()()(2)()()()) // ~> 2
console.log(nice(2)()(1) + '') // ~> '3'
console.log(nice()(3)() == 3) // ~> true
console.log(nice()(3)() === 3) // ~> false
The trick is that adding unary + or using non-strict equality calls valueOf
method right after all function calls, so we've got ourselves an infinite currying :)
And list currying to answer your question. It works because '' +
forces toString method to be called:
const nice = (...args) => {
return Object.assign(
nice.bind(0, ...args),
{ toString: () => JSON.stringify(args) }
)
}
console.log('' + nice(1,2)(3)(4)(5)(6,7)) // ~> [1,2,3,4,5,6,7]
By the way, it's possible to make this infinite currying even more legit, because it can take any type and any amount of parameters which is really cool.
Upvotes: 0
Reputation: 50654
If you can use a final parameter(like "x") to signify end, you can use .bind
const getParameters = function(...arg) {
if (arg[arg.length - 1] !== 'x') {
return getParameters.bind(null, ...arg);
}
arg.pop();
return arg;
};
console.info(getParameters(1)(2)(5)('x'));
console.info(getParameters(1)(2)(5)(20)("x"))
Upvotes: 0
Reputation: 71
Not very good solution, but... Try this one if you want to have a string in output.
function getParameters(a) {
let parameters = '[';
parameters += `${a}`;
function innerFunction(b) {
parameters += `,${b}`;
return innerFunction;
}
innerFunction.toString = function() {
return `${parameters}]`;
};
return innerFunction;
}
console.log(getParameters(1)(3)(4)); //[1,3,4]
Upvotes: 0
Reputation: 11001
UPDATE: Support unlimited arguments. PS: only limitation is when you need to end the call, you have pass last call as null or undefined or empty as shown below.
const getParameters = a => {
const parameters = [a];
const innerFunction = b => {
if (b) {
parameters.push(b);
return innerFunction;
}
return parameters;
};
return innerFunction;
};
console.log(getParameters(1)(2)(5)());
console.log(getParameters(1)(2)(5)(9)(20)(22)());
Upvotes: 0
Reputation: 2483
const getParameters = a => b => c => [a, b, c];
console.log(getParameters(1)(2)(5));
Upvotes: 1