JavaScript function in a function - javascript

I have tried to get this q but without any success...
The task is to build a function by this conditions:
// b('m') -> 'bm'
// b()()('m') -> 'boom'
// b()()()()('m') -> 'boooom'
That is my try:
var b = (a) => {
var counter = 0;
var times = counter += 1;
var d = (a, o, times) => {
var o = 'o'.repeat(times);
return ('b' + o + a);
};
return d();
};
console.log(b('m'));

You need to return a function when the input is not 'm' – returning d () is not returning a function, it's returning the result of a call to d
Here's a way you can do it using an optional parameter with a default value
const b = (a, acc = 'b') =>
a === 'm'
? acc + a
: a => b (a, acc + 'o')
console.log (b ('m'))
console.log (b () ('m'))
console.log (b () () ('m'))
console.log (b () () () ('m'))
And another way using continuation-passing style
const b = (a, k = m => 'b' + m) =>
a === 'm'
? k (a)
: a => b (a, m =>
k ('o' + m))
console.log (b ('m'))
console.log (b () ('m'))
console.log (b () () ('m'))
console.log (b () () () ('m'))
Some people complain about things they don't understand - here's the same function using imperative style
function b (a, acc = 'b')
{
if (a === 'm')
return a
else
return a => b (a, acc + 'o')
}

As another variant of what naomik and NinaScholz proposed, you could avoid the extra optional argument, and use the this context (in ES6) to store a number primitive value that tracks how many 'o' characters to produce:
function b(a) {
return a ? 'b' + 'o'.repeat(+this) + a : b.bind((+this||0)+1);
}
console.log(b('m'));
console.log(b()('m'));
console.log(b()()('m'));
console.log(b()()()('m'));
The string is only composed when b is called with a (truthy) argument: that string is a "b" followed by a number of "o" characters (determined by this) and finally the argument (i.e. "m" in the actual calls). If this is not defined (or is the global object, in non-strict mode), the count of "o" is considered to be 0. This happens when b is called immediately with an argument (no chaining).
When b is called without argument, the function itself is returned, but with a this bound to it that has been increased with 1. NB: so it is not actually the function itself, but a bound variant of it.

You could return use Function#bind and use a temporary this.
function b() {
return arguments.length
? (this.value || 'b') + arguments[0]
: b.bind({ value: (this.value || 'b') + 'o' });
}
console.log(b('m'));
console.log(b()('m'));
console.log(b()()('m'));
console.log(b()()()('m'));

function b must return itself binded to number + 1 if it was called with no params. and return a string bo.(n times).om.
b is initially binded to 0.
let b = (function boom(number, value) {
if (value === 'm') {
return 'b' + 'o'.repeat(number) + 'm';
}
else {
return boom.bind(null, number + 1);
}
}).bind(null, 0); // number value is initialized to 0
console.log(b()()('m')); // boom

Related

Recursive call to a monotonic function with an IIFE stop or creating add function that returns unknown num of functions for adding the next number [duplicate]

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

Calling a value of a ternary operator in 1 line

I have this ternary operator
function digPow(n, p){
return Number.isInteger((""+n).split("").map((num,index) => Math.pow(parseInt(num),(p+index))).reduce((a, b) => a + b, 0)/n) ? (""+n).split("").map((num,index) => Math.pow(parseInt(num),(p+index))).reduce((a, b) => a + b, 0)/n : -1;
}
As you can see this is a very long 1 liner. My question is, how do I recall the value inside the Number.isInteger() so that I don't have to repeat it again for the ternary operator in only 1 line.
This is the code I need a value from:-
(""+n).split("").map((num,index) => Math.pow(parseInt(num),(p+index)))
.reduce((a, b) => a + b, 0)/n
Is there any syntax for this? I am relatively new to JS
EDIT: The main question is actually: "Is it possible to call the value from inside a ternary operator without using a variable"
EDIT-2: Sorry for my bad coding. Here is a simpler way to ask my question
const x = 6
const y = 3
console.log(Number.isInteger(x+y/3) ? x+y/3 : -1)
Is it possible to recall the x+y/3 value without repeating it or making a new variable?
Not exactly sure, what your function is doing or what arguments it's supposed to take, but you could use a Self-Executing Anonymous Function
aka IIFE (Immediately Invoked Function Expression).
Let's start by formatting what you currently have:
const digPow = (n, p) => Number.isInteger(
("" + n)
.split("")
.map((num, index) => Math.pow(parseInt(num), (p + index)))
.reduce((a, b) => a + b, 0) / n
)
? ("" + n)
.split("")
.map((num, index) => Math.pow(parseInt(num), (p + index)))
.reduce((a, b) => a + b, 0) / n
: -1;
console.log(digPow(6, 3)); // 36
It looks like this part is inside the condition and also a return if the result is an integer:
("" + n)
.split("")
.map((num, index) => Math.pow(parseInt(num), (p + index)))
.reduce((a, b) => a + b, 0) / n
You can reduce your logic to the following (pseudo-code):
const digPow = (x => Number.isInteger(x) ? x : -1)(split/map/reduce/divide);
Let's pass that into an IIFE:
const digPow = (n, p) => (
(value) => Number.isInteger(value) ? value : -1)
(("" + n)
.split("")
.map((num, index) => Math.pow(parseInt(num), (p + index)))
.reduce((a, b) => a + b, 0) / n);
console.log(digPow(6, 3)); // 36

How can this chaining be achieved in Javascript? [duplicate]

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

"Maximum call stack size exceeded" Calling function from inside the function

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

How do you curry any javascript function of arbitrary arity?

Let's say I have some function:
function g(a,b,c){ return a + b + c }
And I'd like to turn it into its "curried" form (in quotations since it's not exactly curried per se):
function h(a,b,c){
switch(true){
case (a !== undefined && b !== undefined && c !== undefined):
return a + b + c
case (a !== undefined && b !== undefined && c === undefined):
return function(c){ return a + b + c }
case (a !== undefined && b == undefined && c === undefined ):
return function(b,c){
return (c === undefined) ? function(c){ return a + b + c } : a + b + c
}
default:
return h
}
}
The above form has the partial binding behavior I want:
h(1) -> h(b,c)
h(1,2) -> h(c)
h(1,2,3) -> 6
h() -> h(a,b,c)
Now I'd like to automate this process into some generic function curry such that given any un-curried function (and maybe its number of parameters), the above function is generated. But I'm not quite sure how to implement it.
Alternatively, if the following form could be automatically created, it'd be also interesting:
function f(a,b,c){
return function(a){ return function(b){ return function(c){ return a + b + c }}}
}
Though binding f looks like this:
f(1)(2)(3) = 6
so it is very unwieldily and non-idiomatic, but creating the above form seem more feasible to me.
Now is could any of the above form be generated by some function, if so, how?
I believe that you could simply use Function.prototype.bind. That gives you all the flexibility you need, wheter you want the result of the function right away or simply push another value into the arguments until you decide to execute.
function sum() {
return [].reduce.call(arguments, function (c, n) {
return c + n;
});
}
sum(1, 2); //3
var sum2 = sum.bind(null, 1, 2);
sum2(); //3
var sum3 = sum2.bind(null, 3);
sum3(); //6
You could also use a helper function like:
function curry(fn) {
var c = curry.bind(this, fn = fn.bind.apply(fn, [this].concat([].slice.call(arguments, 1))));
c.exec = fn;
return c;
}
curry(sum, 1, 2)(3)(4, 5)(6, 7, 8).exec(); //36
Also this is very flexible as you do not have to chain, you can re-use the same curried function.
var sumOnePlus = curry(sum, 1);
sumOnePlus.exec(2); //3;
sumOnePlus.exec(3); //4;
Here's my attempt:
function curry(fn, len) {
if (typeof len != "number")
len = fn.length; // getting arity from function
return function curried() {
var rlen = len - arguments.length;
if (rlen <= 0) // then execute now
return fn.apply(this, arguments);
// else create curried, partially bound function:
var bargs = [this]; // arguments for `bind`
bargs.push.apply(bargs, arguments);
return curry(fn.bind.apply(fn, bargs), rlen);
};
}
This does not partial application (which is easy in JS with the bind method), but true functional currying. It works with any functions of arbitrary, but fixed arity. For variadic functions you would need a different execution trigger, maybe when no arguments are passed any more or an exec method like in #plalx' answer.
How about something like this:
function makeLazy(fn) {
var len = fn.length;
var args = [];
return function lazy() {
args.push.apply(args, arguments);
if (args.length < len) {
return lazy;
} else {
return fn.apply(this, args);
}
}
}
function f(a,b,c) { return a + b + c; }
var lazyF = makeLazy(f);
lazyF(1)(2)(3); // 6
var lazyF = makeLazy(f);
lazyF(1,2)(3); // 6
If you wanted a reusable function (I guess I can't tell exactly what you want), then this would work:
function makeCurry(fn) {
return function curry() {
var args = [].slice.call(arguments);
return function() {
return fn.apply(this, args.concat.apply(args, arguments));
};
}
}
function f(a,b,c) { return a + b + c; }
var curryF = makeCurry(f);
var addOneTwoAnd = curryF(1,2);
addOneTwoAnd(3); // 6
addOneTwoAnd(6); // 9
Please check the curry library.
It can turn any function into curry no matter how many arguments are there.
Example:
> var curry = require('curry');
undefined
> var add = curry(function(a, b, c, d, e) { return a + b + c + d + e; });
undefined
> add(1)
[Function]
> add(1,2,3,4,5)
15
> add(1,2)(3,4)(5)
15
>
The bind() method on function lets you bind the this inside the function as well as bind extra parameters. So, if you pass null for the this parameter, you can use bind() to curry the parameters into the function.
function g(a,b,c){ return a + b + c }
var g_1 = g.bind(null, 1);
console.log(g_1(2, 3)); // Prints 6
var g_1_2 = g.bind(null, 1, 2);
console.log(g_1_2(3)); // Prints 6
Check Javascript Function bind() for details and interactive examples of using bind() to bind parameters.

Categories