Ala*_*anH 6 javascript currying
说我有一个叫做的函数 multiplyDivide
如果我打电话multiplyDivide(2)(3)(4)(6),那就相当于2 * 3 / 4 * 6.
更新:
如果我事先不知道将要采用多少参数,是否可以编写这样的函数?例如,我可以multiplyDivide(1)(2)或multiplyDivide(1)(2)(3)(4)...(n-1)(n)
sle*_*man 12
这有点可能,但您需要定义终止条件,因为问题与编写递归函数的问题基本相同.该函数需要一种方法来告诉天气它应该返回一个函数或一个值.
您如何表达对价值的需求取决于您.一种方法是检查参数是否通过:
// Using add instead of multiplyDivide to simplify example:
function add (num) {
function adder (n) {
if (n !== undefined) {
num += n;
return adder;
}
else { // terminate
return num;
}
}
return adder;
}
Run Code Online (Sandbox Code Playgroud)
现在你可以这样做:
var sum = add(1)(2)(3)(4)();
Run Code Online (Sandbox Code Playgroud)
否则它会返回一个你可以继续调用的函数:
var x = add(1)(2)(3)(4);
x = x(5)(6)(7);
x = x(8)(9)(10);
var sum = x();
Run Code Online (Sandbox Code Playgroud)
由于在js函数中是对象,因此您还可以将值getter实现为静态方法.它不是纯粹的功能,但使"API"更明确,更容易阅读:
function add (num) {
function adder (n) {
num += n;
return adder;
}
adder.value = function(){
return num
};
return adder;
}
Run Code Online (Sandbox Code Playgroud)
这将允许你做:
var sum = add(1)(2)(3)(4).value();
Run Code Online (Sandbox Code Playgroud)
您甚至可以通过覆盖内置.valueOf()和.toString()方法来获得幻想:
function add (num) {
function adder (n) {
num += n;
return adder;
}
adder.valueOf = function(){
return num
};
adder.toString = function(){
return '' + num
};
return adder;
}
Run Code Online (Sandbox Code Playgroud)
这将允许你做:
var sum = add(1)(2)(3)(4) + 5; // results in 15
var txt = add(1)(2)(3)(4) + "hello"; // results in "10hello"
Run Code Online (Sandbox Code Playgroud)
这里的关键是你需要一种方法来告诉函数停止返回函数.
使用函数方法,您可以创建一个函数来“柯里化”另一个函数的参数。您将需要一种方法来告诉函数返回值,因此在这种情况下,调用函数而不传递任何参数将返回结果:
function curry(fn, ...values) {
return (...next) => (next.length) ? curry(fn, ...values, ...next) : fn(...values);
}
Run Code Online (Sandbox Code Playgroud)
该函数最酷的一点是您可以传递多个参数和/或继续调用该函数(1)(2, 3, 4)(5)。
这里有几个例子:
function curry(fn, ...values) {
return (...next) => (next.length) ? curry(fn, ...values, ...next) : fn(...values);
}
Run Code Online (Sandbox Code Playgroud)
当然,这个示例确实暗示只是简单地重载该multiplyDivide函数并在准备好时将您的值传递给该函数:
function curry(fn, ...values) {
return (...next) => (next.length) ? curry(fn, ...values, ...next) : fn(...values);
}
function multiplyDivide(...args) {
return args.reduce((total, next, i) => (i % 2) ? (total / next) : (total * next), args.shift());
}
let x = curry(multiplyDivide)(2)(3, 4)(6)();
console.log(x);
let y = curry(multiplyDivide)(5, 4, 2)(3);
y = y(3, 5)(1)();
console.log(y);Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1926 次 |
| 最近记录: |