BFE.devAI解答 - JavaScript 代码题
2. 实现支持placeholder的curry()
解题思路:
在实现带有占位符的curry()
函数之前,我们需要对之前实现的基本curry()
函数进行修改,使其支持传递占位符。
对于curry()
函数的调用,我们需要增加一个新的可选参数placeholder
,默认值为Symbol('_')
,表示占位符。在返回的柯里化函数中,我们可以使用Array.prototype.reduce()
方法来判断每一个参数是否是占位符,如果是,那么用下一个传入的参数替换占位符,然后继续执行,直到所有的占位符都被替换为实际值。
具体实现可以参考以下代码:
解题代码:
const curry = (fn, placeholder = Symbol('_')) => { const curried = (...args) => { return (args.includes(placeholder) || args.length < fn.length) ? (...newArgs) => curried( ...args.map(arg => arg === placeholder ? newArgs.shift() : arg), ...newArgs ) : fn(...args) } return curried}curry.placeholder = Symbol('_')export default curry
接下来,我们需要实现支持占位符的curry()
函数。对于这个函数,我们需要解决以下两个问题:
-
如何处理占位符
-
发送错误消息,如果没有传递足够数量的参数
对于第一个问题,我们可以遇到占位符时将其替换为下一个参数,然后继续执行。
对于第二个问题,我们可以对传递给柯里化函数的参数数量和函数的参数数量进行比较,并根据需要抛出异常或递归调用柯里化函数。
具体实现可以参考以下代码:
完整代码如下:
const curry = (fn, placeholder = Symbol('_')) => { const curried = (...args) => { return (args.includes(placeholder) || args.length < fn.length) ? (...newArgs) => curried( ...args.map(arg => arg === placeholder ? newArgs.shift() : arg), ...newArgs ) : fn(...args) } return curried}curry.placeholder = Symbol('_')const join = (a, b, c) => { return `${a}_${b}_${c}`}const curriedJoin = curry(join)console.log(curriedJoin(1, 2, 3)) // '1_2_3'console.log(curriedJoin(curry.placeholder, 2)(1, 3)) // '1_2_3'console.log(curriedJoin(curry.placeholder, curry.placeholder, curry.placeholder)(1)(curry.placeholder, 3)(2)) // '1_2_3'export default curry