Question #
Please design a currying function to achieve the following effects:
function join(a, b, c) {
return `${a}_${b}_${c}`
}
const curriedJoin = curry(join)
console.log(curriedJoin(1, 2, 3)) // '1_2_3'
console.log(curriedJoin(1)(2, 3)) // '1_2_3'
console.log(curriedJoin(1, 2)(3)) // '1_2_3'
console.log(curriedJoin(1)(2)(3)) // '1_2_3'Solution #
function curry(fn) {
const context = this
return function curried(...args) {
if (args.length >= fn.length) {
return fn.apply(context, args)
}
return function (...restArgs) {
return curried.apply(context, args.concat(restArgs))
}
}
}
function join(a, b, c) {
return `${a}_${b}_${c}`
}
const curriedJoin = curry(join)
console.log(curriedJoin(1, 2, 3)) // '1_2_3'
console.log(curriedJoin(1)(2, 3)) // '1_2_3'
console.log(curriedJoin(1, 2)(3)) // '1_2_3'
console.log(curriedJoin(1)(2)(3)) // '1_2_3'Or, we can use the bind method to achieve the same effect:
function curry(fn) {
const context = this
return function curried(...args) {
if (args.length >= fn.length) {
return fn.apply(context, args)
}
return curried.bind(context, ...args)
}
}Or, we can use arrow function to achieve the same effect:
function curry(fn) {
const curried = (...args) => {
if (args.length >= fn.length) {
return fn(...args)
}
return (...restArgs) => curried(...args, ...restArgs)
}
return curried
}