咖喱javascript sum函数。

时间:2018-08-22 01:27:15

标签: javascript recursion closures

我遇到了一个有趣的问题。编写一个javascript函数,该函数通过多次调用同一函数来返回传递给它的所有参数的总和。

以下是调用函数的方法-

sum(1, 2, 3, 4);
sum(1, 2)(3, 4);
sum(1, 2)(3)(4);
sum(1, 2, 3)(4);
sum(1)(2, 3, 4);

以上所有调用均应正常工作并返回10。

这是我到目前为止所写的内容,但是它仅适用于前两个函数调用sum(1, 2, 3, 4)sum(1, 2)(3, 4),其余部分都无法使用。

const arr = [];

function sum(...args) {
  if (args.length === 4) {
    return args.reduce((acc, curr) => {
      return (acc = acc + curr);
    }, 0);
  } else {
    arr.push(...args);
    return function(...args) {
      arr.push(...args);
      return sum(...arr);
    };
  }
}

请有人帮我,这真让我发疯。

谢谢!

2 个答案:

答案 0 :(得分:6)

您非常接近。如果您尚未获得至少四个参数,这是使用.bind方法返回捕获第一个参数的函数的绝好机会。

类似这样:

function sum(...args) {
  if (args.length >= 4) {
    return args.reduce((acc, curr) => {
      return (acc = acc + curr);
    }, 0);
  } else {
    // Bind the arguments you have to this function, and return it:
    return sum.bind(null, ...args)
  }
}

console.log(sum(1, 2, 3, 4));
console.log(sum(1, 2)(3, 4));
console.log(sum(1, 2)(3)(4));
console.log(sum(1, 2, 3)(4));
console.log(sum(1)(2, 3, 4));

最后,我将更改条件以检查>= 4,以便在不超过该次数的情况下不会永远咖喱。

答案 1 :(得分:1)

由于不确定的Arity,Currying具有特定的定义行为,不能与可变参数函数很好地混合。但是,在您遇到的特定问题中,您指定了一个Arity(例如4),因此可以知道何时返回结果

const curryN = (n, f, ...xs) =>
  (...ys) =>
    ys.length >= n
      ? f (...xs, ...ys)
      : curryN (n - ys.length, f, ...xs, ...ys)
      
const add = (...numbers) =>
  numbers.reduce ((a, b) => a + b, 0)
  
const curryAdd =
  curryN (4, add)
  
console.log
  ( curryAdd (1) (2) (3) (4) // 10
  , curryAdd (1, 2) (3, 4)   // 10
  , curryAdd (1, 2, 3) (4)   // 10
  , curryAdd (1) (2, 3, 4)   // 10
  , curryAdd (1, 2, 3, 4)    // 10
  )

这是设计程序的脆弱方法,甚至不是 true currying,每个应用程序仅接受1个参数。部分应用程序更好,因为它可以生成行为更可靠的程序

const partial = (f, ...xs) =>
  (...ys) =>
    f (...xs, ...ys)
    
const add = (...numbers) =>
  numbers.reduce ((a, b) => a + b, 0)
  
console.log
  ( partial (add, 1) (2, 3, 4) // 10
  , partial (add, 1, 2) (3, 4) // 10
  , partial (add, 1, 2, 3) (4) // 10
  )

请阅读此related answer,以获取更多信息。