可变curry求和函数
Variadic curried sum function
我需要一个js sum函数像这样工作:
sum(1)(2) = 3
sum(1)(2)(3) = 6
sum(1)(2)(3)(4) = 10
etc.
我听说这是不可能的。但是听说如果在sum
前面加+
就可以了。比如+sum(1)(2)(3)(4)
。
有什么好主意吗?
不知道我是否明白你想要什么,但是
function sum(n) {
var v = function(x) {
return sum(n + x);
};
v.valueOf = v.toString = function() {
return n;
};
return v;
}
console.log(+sum(1)(2)(3)(4));
JsFiddle
这是一个在最后一次通话中使用空括号作为关闭键的例子(来自我上次的面试):
(1)和(4)(66)(35)(0)()
function sum(firstNumber) {
let accumulator = firstNumber;
return function adder(nextNumber) {
if (nextNumber === undefined) {
return accumulator;
}
accumulator += nextNumber;
return adder;
}
}
console.log(sum(1)(4)(66)(35)(0)());
我把这个修订作为自己的帖子发布,因为我显然还没有足够的声誉来留下评论。这是@Rafael的优秀解决方案的修订版。
function sum (n) {
var v = x => sum (n + x);
v.valueOf = () => n;
return v;
}
console.log( +sum(1)(2)(3)(4) ); //10
我没有看到保留v.toString
位的理由,因为它似乎没有必要。如果我这样做错了,请在评论中告诉我为什么需要v.toString(没有它它通过了我的测试)。为方便阅读,将其余匿名函数转换为箭头函数
新的ES6方式和简洁。
当你想要终止调用并获得最终值时,你必须在最后传递empty()。
const sum= x => y => (y !== undefined) ? sum(x + y) : x;
这样称呼它-
sum(10)(30)(45)();
这是一个使用ES6和toString
的解决方案,类似于@ venba
function add(a) {
let curry = (b) => {
a += b
return curry
}
curry.toString = () => a
return curry
}
console.log(add(1))
console.log(add(1)(2))
console.log(add(1)(2)(3))
console.log(add(1)(2)(3)(4))
另一个略短的方法:
const sum = a => b => b? sum(a + b) : a;
console.log(
sum(1)(2)(),
sum(3)(4)(5)()
);
下面是ES6 Javascript中使用通用可变curry函数的解决方案,需要注意的是需要一个最终的()
来调用参数:
const curry = (f) =>
(...args) => args.length? curry(f.bind(0, ...args)): f();
const sum = (...values) => values.reduce((total, current) => total + current, 0)
curry(sum)(2)(2)(1)() == 5 // true
这是另一个不需要()
,使用valueOf
在@拉斐尔的回答。我觉得以这种方式使用valueOf
(或者可能根本)对阅读您的代码的人来说非常令人困惑,但每个人都有自己的想法。
答案中的toString
是不必要的。在内部,当javascript执行类型转换时,它总是在调用toString()
之前调用valueOf()
。
// invokes a function if it is used as a value
const autoInvoke = (f) => Object.assign(f, { valueOf: f } );
const curry = autoInvoke((f) =>
(...args) => args.length? autoInvoke(curry(f.bind(0, ...args))): f());
const sum = (...values) => values.reduce((total, current) => total + current, 0)
curry(sum)(2)(2)(1) + 0 == 5 // true
试试这个,这样处理任何类型的输入都更灵活。你可以传递任意数量的参数和任意数量的括号。
function add(...args) {
function b(...arg) {
if (arg.length > 0) {
return add(...[...arg, ...args]);
}
return [...args, ...arg].reduce((prev,next)=>prev + next);
}
b.toString = function() {
return [...args].reduce((prev,next)=>prev + next);
}
return b;
}
// Examples
console.log(add(1)(2)(3, 3)());
console.log(+add(1)(2)(3)); // 6
console.log(+add(1)(2, 3)(4)(5, 6, 7)); // 28
console.log(+add(2, 3, 4, 5)(1)()); // 15
这里有一个更通用的解决方案,也适用于非一元参数:
const sum = function (...args) {
let total = args.reduce((acc, arg) => acc+arg, 0)
function add (...args2) {
if (args2.length) {
total = args2.reduce((acc, arg) => acc+arg, total)
return add
}
return total
}
return add
}
document.write( sum(1)(2)() , '<br/>') // with unary params
document.write( sum(1,2)() , '<br/>') // with binary params
document.write( sum(1)(2)(3)() , '<br/>') // with unary params
document.write( sum(1)(2,3)() , '<br/>') // with binary params
document.write( sum(1)(2)(3)(4)() , '<br/>') // with unary params
document.write( sum(1)(2,3,4)() , '<br/>') // with ternary params
试试这个
function sum (...args) {
return Object.assign(
sum.bind(null, ...args),
{ valueOf: () => args.reduce((a, c) => a + c, 0) }
)
}
console.log(+sum(1)(2)(3,2,1)(16))
在这里你可以看到一篇关于带无限参数的函数的中篇文章
https://medium.com/@seenarowhani95无限-局部套用在javascript - 38400827 e581
ES6解决无限套用的方法。这里,函数sum将返回参数中传递的所有数字的和:
const sum = a => b => b ? sum(a + b) : a
sum(1)(2)(3)(4)(5)() // 15
function add(a) {
let curry = (b) => {
a += b
return curry;
}
curry[Symbol.toPrimitive] = (hint) => {
return a;
}
return curry
}
console.log(+add(1)(2)(3)(4)(5)); // 15
console.log(+add(6)(6)(6)); // 18
console.log(+add(7)(0)); // 7
console.log(+add(0)); // 0
这是使用迭代过程的另一种功能方法
const sum = (num, acc = 0) => {
if !(typeof num === 'number') return acc;
return x => sum(x, acc + num)
}
sum(1)(2)(3)()
和一行
const sum = (num, acc = 0) => !(typeof num === 'number') ? acc : x => sum(x, acc + num)
sum(1)(2)(3)()
我们也可以用这种简单的方法。
function sum(a) {
return function(b){
if(b) return sum(a+b);
return a;
}
}
console.log(sum(1)(2)(3)(4)(5)());
你可以使用下面的函数
function add(num){
add.sum || (add.sum = 0) // make sure add.sum exists if not assign it to 0
add.sum += num; // increment it
return add.toString = add.valueOf = function(){
var rtn = add.sum; // we save the value
return add.sum = 0, rtn // return it before we reset add.sum to 0
}, add; // return the function
}
由于函数是对象,我们可以给它添加属性,当它被访问时,我们会重置这些属性。
要使sum(1)
像sum(1)(2)
一样可调用,它必须返回一个函数。
函数可以调用,也可以用valueOf
转换为数字。
function sum(a) {
var sum = a;
function f(b) {
sum += b;
return f;
}
f.toString = function() { return sum }
return f
}
function sum(a){
let res = 0;
function getarrSum(arr){
return arr.reduce( (e, sum=0) => { sum += e ; return sum ;} )
}
function calculateSumPerArgument(arguments){
let res = 0;
if(arguments.length >0){
for ( let i = 0 ; i < arguments.length ; i++){
if(Array.isArray(arguments[i])){
res += getarrSum( arguments[i]);
}
else{
res += arguments[i];
}
}
}
return res;
}
res += calculateSumPerArgument(arguments);
return function f(b){
if(b == undefined){
return res;
}
else{
res += calculateSumPerArgument(arguments);
return f;
}
}
}
let add = (a) => {
let sum = a;
funct = function(b) {
sum += b;
return funct;
};
Object.defineProperty(funct, 'valueOf', {
value: function() {
return sum;
}
});
return funct;
};
console.log(+add(1)(2)(3))
在看过这里的其他一些解决方案之后,我想提供我对这个问题的两个解决方案。
在ES6中嵌套两个条目:
const sum = x => y => (y !== undefined ) ? +x + +y : +x
sum(2)(2) // 4
这里我们指定了两个参数,如果第二个参数不存在,我们只返回第一个参数。
对于三个或更多项,它变得有点棘手;这是我的解决方案。对于任何其他参数,您可以将它们作为第三个
添加进去。const sum = x => (y=0) => (...z) => +x + +y + +z.reduce((prev,curr)=>prev+curr,0)
sum(2)()()//2
sum(2)(2)()//4
sum(2)(2)(2)//6
sum(2)(2)(2,2)//8
希望对大家有所帮助
- 创建一个类似链接的按钮,并通过Javascript函数打开一个新的弹出窗口
- 将函数的上下文应用于javascript变量
- 如何在JavaScript中将字符串转换为函数引用
- 如何在JavaScript中使用此函数对范围内的所有数字求和
- 使用绑定的简单JavaScript/jQuery求和函数
- Javascript Array 的求和函数问题
- 角度 - 使用函数对数字求和并将其放入视图中
- onChange函数,求和值
- Datatables插件求和函数
- 对多个函数求和
- 试图创建一个对数字求和的Javascript函数
- 对javascript构造函数中的参数求和并返回total
- 函数在不使用parseInt的情况下求和以2为基数的数字的值
- 如何在javascript中求和两个不同的函数
- 如何使用jquery-onlick函数对表单文本字段数组中的值求和
- 当对数组元素求和时,递归函数根据顺序返回不同的值
- 如何在异步函数中对 Javascript 数组的值求和
- 可变curry求和函数
- JavaScript求和函数
- JQuery函数格式和求和或2个文本框的问题