Question #
please implement curry() which also supports placeholder.
Here is an example
function join(a, b, c) {
return `${a}_${b}_${c}`
}
const curriedJoin = curry(join)
const _ = curry.placeholder
curriedJoin(1, 2, 3) // '1_2_3'
curriedJoin(_, 2)(1, 3) // '1_2_3'
curriedJoin(_, _, _)(1)(_, 3)(2) // '1_2_3'Solution #
Let’s compare with following arguments:
- (_, _, _) with (1) , we can get (1, _, _)
- (1, _, ) with (, 3) , we can get (1, _, 3)
- (1, _, 3) with (2) , we can get (1, 2, 3)
We can find a pattern: if this call including placeholder argument, the next call’s arguments will fill the placeholder of the last call’s rest placeholder arguments.
Now, we have understand the question, so we can implement it.
function curry(fn) {
const context = this
return function curried(...args) {
const isComplete = args.length >= fn.length && !args.slice(0, fn.length).includes(curry.placeholder)
if (isComplete) {
return fn.apply(context, args)
}
return function (...nextArgs) {
const argList = args.map((arg) => {
return arg === curry.placeholder && nextArgs.length ? nextArgs.shift() : arg
})
return curried.apply(context, argList.concat(nextArgs))
}
}
}