I need a js sum function to work like this:
sum(1)(2) = 3
sum(1)(2)(3) = 6
sum(1)(2)(3)(4) = 10
etc.
I heard it can't be done. But heard that if adding + in front of sum can be done.
Like +sum(1)(2)(3)(4). Any ideas of how to do this?
Not sure if I understood what you want, but
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
This is an example of using empty brackets in the last call as a close key (from my last interview):
sum(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)());
I'm posting this revision as its own post since I apparently don't have enough reputation yet to just leave it as a comment. This is a revision of #Rafael 's excellent solution.
function sum (n) {
var v = x => sum (n + x);
v.valueOf = () => n;
return v;
}
console.log( +sum(1)(2)(3)(4) ); //10
I didn't see a reason to keep the v.toString bit, as it didn't seem necessary. If I erred in doing so, please let me know in the comments why v.toString is required (it passed my tests fine without it). Converted the rest of the anonymous functions to arrow functions for ease of reading.
New ES6 way and is concise.
You have to pass empty () at the end when you want to terminate the call and get the final value.
const sum= x => y => (y !== undefined) ? sum(x + y) : x;
call it like this -
sum(10)(30)(45)();
Here is a solution that uses ES6 and toString, similar to #Vemba
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))
Another slightly shorter approach:
const sum = a => b => b? sum(a + b) : a;
console.log(
sum(1)(2)(),
sum(3)(4)(5)()
);
Here's a solution with a generic variadic curry function in ES6 Javascript, with the caveat that a final () is needed to invoke the arguments:
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
Here's another one that doesn't need (), using valueOf as in #rafael's answer. I feel like using valueOf in this way (or perhaps at all) is very confusing to people reading your code, but each to their own.
The toString in that answer is unnecessary. Internally, when javascript performs a type coersion it always calls valueOf() before calling toString().
// 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
Try this
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))
Here you can see a medium post about carried functions with unlimited arguments
https://medium.com/#seenarowhani95/infinite-currying-in-javascript-38400827e581
Try this, this is more flexible to handle any type of input. You can pass any number of params and any number of paranthesis.
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
Here's a more generic solution that would work for non-unary params as well:
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
ES6 way to solve the infinite currying. Here the function sum will return the sum of all the numbers passed in the params:
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
Here is another functional way using an iterative process
const sum = (num, acc = 0) => {
if !(typeof num === 'number') return acc;
return x => sum(x, acc + num)
}
sum(1)(2)(3)()
and one-line
const sum = (num, acc = 0) => !(typeof num === 'number') ? acc : x => sum(x, acc + num)
sum(1)(2)(3)()
You can make use of the below function
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
}
Since functions are objects, we can add properties to it, which we are resetting when it's been accessed.
we can also use this easy way.
function sum(a) {
return function(b){
if(b) return sum(a+b);
return a;
}
}
console.log(sum(1)(2)(3)(4)(5)());
To make sum(1) callable as sum(1)(2), it must return a function.
The function can be either called or converted to a number with 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))
After looking over some of the other solutions on here, I would like to provide my two solutions to this problem.
Currying two items using ES6:
const sum = x => y => (y !== undefined ) ? +x + +y : +x
sum(2)(2) // 4
Here we are specifying two parameters, if the second one doesnt exist we just return the first parameter.
For three or more items, it gets a bit trickier; here is my solution. For any additional parameters you can add them in as a third
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
I hope this helped someone
I'm trying to make a function that accepts another function and outputs that function repeatedly by only using function expressions/applications.
So far I have a function twice which accepts another function as an argument and returns func(func(x)):
function twice(func) {
function x(x) {
return func(func(x));
}
return x;
}
I'm trying to make a repeater function such that const thrice = repeater(twice) returns func(func(func(x))), and const fourtimes = repeater(thrice) etc. but i'm confused as to how to do this. Any help would be appreciated greatly. Thank you
Using your current structure thats impossible as twice does not expose a reference to func, thus repeater cannot call it.
The only solution I could think of would be to leak func from the inside through a (hidden) property:
const r = Symbol();
const repeater = f => Object.assign(
v => f[r] ? f(f[r](v)): f(v),
{ [r]: f[r] || f }
);
const addThree = repeater(repeater(repeater(n => n + 1)));
console.log(addThree(10));
You should two base cases (if n == 0 => exit, if n == 1 => return f(x)), where n is an additional parameter that specifies how many times the function should repeat with the arguments args:
function repeater(func, x, n) {
if (n == 0) return;
if (n == 1) return func(x);
else {
return func(repeater(func, x, --n));
}
}
let sqr = n => n * n;
console.log(repeater(sqr, 2, 3));
Do you look for something like this?
function chain(f, g) {
return function (x) {
return f(g(x));
}
}
function ntimes(f, n) {
if (n == 0) {
return function (x) { return x }
} else {
return chain(f, ntimes(f, n-1));
}
}
This will make a new function which repeats the original function f n times.
This question already has an answer here:
Writing a function f which would satisfy the following test
(1 answer)
Closed 3 years ago.
f()()('x') // foox
f()()()()('x') //foooox
I tried to return nested functions but unable to get desired result.
You can create a function that returns function or result based on passed argument assuming that only last call have an argument passed.
function f() {
let os = ''
return function again(x) {
os += 'o'
if (!x) return again;
else return `f${os}${x}`;
}
}
console.log(f()()('x'))
console.log(f()()()()('x'))
console.log(f()()()()()()('Y'))
Just use a counter variable and return a function if the variable is not defined.
const f = (a, c = 0) => a ? "f" + "o".repeat(c) + a : b => f(b, ++c);
console.log(f()()("x"));
console.log(f()()()()("z"));
ES5 syntax:
function f(a, c) {
c = c || 0;
if (a) {
return "f" + "o".repeat(c) + a;
} else {
return function(b) {
return f(b, c + 1);
}
}
}
console.log(f()()("x"));
console.log(f()()()()("z"));
You could return a function for more than one call of the function and implement a toString method to get the final string.
function f(v = 'o') {
var s = 'f' + v;
function g(v = 'o') {
s += v;
return g;
};
g.toString = function () { return s; };
return g;
}
console.log(f()()); // foo
console.log(f('it')); // fit
console.log(f()('x')); // fox
console.log(f()()('b')('a')('r')); // foobar
OK, so im trying to make a small sudoku generator, and i didn't get far before i met a problem. I meet the error "Maximum call stack size exceeded" when the output in console.log is "a == b". Here is my code (Im not an experienced coder FUI)
function en_Til_Ni() {
return Math.floor(Math.random()*9)+1;
}
var enTilNi = en_Til_Ni();
console.log(enTilNi);
var a = en_Til_Ni();
console.log("a" + a);
var b = en_Til_Ni();
console.log("b" + b);
var c = en_Til_Ni();
console.log("c" + c);
console.log("---------------------------------------------");
function ikkeLike() { //this is where it goes wrong
if (a != b) {
console.log(a, b);
}
else if (a == b) { // It logs the numbers just fine, untill a == b
ikkeLike();
}
}
ikkeLike();
Of course you are getting this result, because you have no working exit condition.
You neeed to change the random values and check again until the wanted state is reached.
function en_Til_Ni() {
return Math.floor(Math.random() * 9) + 1;
}
function ikkeLike() {
a = en_Til_Ni();
b = en_Til_Ni();
if (a !== b) {
console.log(a, b);
} else { // no need for the opposite check
ikkeLike();
}
}
var a, b; // global variables
ikkeLike();
Better version without recursive call and a do ... while loop.
function en_Til_Ni() {
return Math.floor(Math.random() * 9) + 1;
}
function ikkeLike() {
do {
a = en_Til_Ni();
b = en_Til_Ni();
} while (a === b)
console.log(a, b);
}
var a, b; // global variables
ikkeLike();
This is little hack for your problem :
Use setTimeout to avoid this error message , app see problem with infinity loops .
Also you need to make new values for a and b !
function en_Til_Ni() {
return Math.floor(Math.random()*9)+1;
}
var enTilNi = en_Til_Ni();
console.log(enTilNi);
var a = en_Til_Ni();
console.log("a" + a);
var b = en_Til_Ni();
console.log("b" + b);
var c = en_Til_Ni();
console.log("c" + c);
console.log("---------------------------------------------");
function ikkeLike() {
if (a != b) {
console.log(a, b);
}
else if (parseInt(a) == parseInt(b) ) { // It logs the numbers just fine, untill a == b
console.log (" a == b TRUE" );
a = en_Til_Ni();
b = en_Til_Ni();
c = en_Til_Ni();
setTimeout ( ikkeLike , 1 )
console.log("cool")
}
}
ikkeLike();
OK, so im trying to make a small sudoku generator, and i didn't get
far before i met a problem.
Looks like you want to check if three values you have generated - a, b and c are not equal. And you want to keep generating the values of b and c till they are all different.
Change your method en_Til_Ni in such a way that it will keep generating random values till values are unique.
function en_Til_Ni()
{
var newValue = Math.floor(Math.random()*9)+1;
args = [].slice.call(arguments);
var isNotNew = args.some( function( item ){
item == newValue;
});
return !isNotNew ? newValue : en_Til_Ni.apply( this, args ) ;
}
Now this method will always return unique values
var a = en_Til_Ni();
console.log("a" + a);
var b = en_Til_Ni(a);
console.log("b" + b);
var c = en_Til_Ni(a,b);
console.log("c" + c);
This is a recursion without the increment part. Let's look on ikkeLike() without the first condition:
function ikkeLike() {
// We removed the first case for the simplicity
if (a == b) {
ikkeLike();
}
}
Now you can easly see that in this case it is just an infinite loop...
You need to solve this case by changing 'a' or 'b' just before the recursive call:
function ikkeLike() {
if (a == b) {
// <--Change 'a' or 'b' here before the recursive call to avoid infinite loop!
ikkeLike();
}
}
So I am trying to write a general memoizing function in Javascript, using this as my reference material. I've implemented it as instructed:
function memoize(func) {
var memo = {};
var slice = Array.prototype.slice;
return function() {
var args = slice.call(arguments);
if (args in memo)
return memo[args]
else
return (memo[args] = func.apply(this, args));
}
}
function fibonacci(n) {
if (n === 0 || n === 1)
return n;
else
return fibonacci(n - 1) + fibonacci(n - 2);
}
function memoFib = memoize(fibonacci);
console.log("Fibonacci of 6 is " + memoFib(6));
but for the life of me I cannot remember the proper syntax to calling the memoized function. How do I do this? How do I generalize this so that it's the memoized fibonacci function which is always called instead of the original function fibonacci?
You're almost there; you just need to fix your syntax when creating the memoized function. Instead of function memoFib =, do var memoFib = (or if ES2015 is an option, const would be better than var). And presumably you'll want to have the recursion calling into the memoized version as well, so i updated those as well. In the following code it may look weird that i'm referencing memoFib on a line that comes earlier than the line with var memoFib but javascript allows that due to hoisting.
function memoize(func) {
var memo = {};
var slice = Array.prototype.slice;
return function() {
var args = slice.call(arguments);
if (args in memo)
return memo[args]
else
return (memo[args] = func.apply(this, args));
}
}
function fibonacci(n) {
if (n === 0 || n === 1)
return n;
else
return memoFib(n - 1) + memoFib(n - 2);
}
var memoFib = memoize(fibonacci);
console.log("Fibonacci of 6 is " + memoFib(6));
And if you want to make absolutely sure no one can ever invoke the nonmemoized version, then you can hide it inside of an IIFE:
const fibonacci = (function () {
function unmemoizedVersion(n) {
if (n === 0 || n === 1)
return n;
else
return fibonacci(n - 1) + fibonacci(n - 2);
}
return memoize(unmemoizedVersion);
})();