← 全部文章

Coding Practice: Implement Currying With Placeholder Support

A JS coding practice: Implement Currying With Placeholder Support

文章目录
  1. Question
  2. Solution

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))
    }
  }
}