passing argument to map function - javascript

I have code like:
var addX = (e) => return e+1;
I am calling like:
[1,2,3].map(addX);
Can I make "1" dynamic? Like:
[1,2,3].map(addX(2)); //this wont work, in this case it should add 2

You need a closure over e and return a function with one parameter for the callback.
var addX = x => v => x + v;
console.log([1, 2, 3].map(addX(2)));

You can use currying like this:
var addX = n => e => e + n;
console.log([1,2,3].map(addX(2)));
console.log([1,2,3].map(addX(10)));
What this does is, you pass the number (n) that you want to be added to the function and it returns a new function which adds that number to it's argument (e) (each element when using map)

You can use bind(thisArg, argument1) to send an extra parameter
var addX = (a, b) => a+b;
console.log("2", [1,2,3].map(addX.bind(Array, 2)))
console.log("5", [1,2,3].map(addX.bind(Array, 5)))
The this argument really does not matter in this case. I just put Array there, it can be this, null, etc.

You can create a function to return a function that takes your add amount.
Here is an example below.
var addX = (addbit) => (e) => e + addbit;
console.log([1,2,3].map(addX(2)));

I would do something like this :)
var addX = (e) => e+1;
[1,2,3].map(num => addX(num))

Several utility libraries like Lodash, Underscore, and Ramda provide a curry() utility function that takes a function and returns a new version of that function that can take the same arguments one at a time, a few at a time, or all at once.
This means that you can create an add function that can either add two numbers right away add(4, 5) or that can "pre-bake" a function with one of the values included: const increment = add(1); console.log(increment(5));
const add = _.curry((x, y) => x + y);
console.log(add(6, 7));
console.log([1,2,3].map(add(10)));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
If you don't want to include a whole library just for this purpose, you can also use this standalone version of curry:
var curryN = (function () {
var slice = Function.prototype.call.bind(Array.prototype.slice);
var bindArr = function (f, arr) { return f.bind.apply(f, [{}].concat(arr)); };
return function curryN(argCount, func) {
return function fn() {
var args = slice(arguments, 0, argCount);
return args.length === argCount
? func.apply({}, args)
: bindArr(fn, args);
};
};
})();
var curry = function curry(func) { return curryN(func.length, func); };
const add = curry((x, y) => x + y);
console.log(add(6, 7));
console.log([1,2,3].map(add(10)));

You can use closure for that:
var addX = inc => e => e + inc;
var res = [1,2,3].map(addX(2));
console.log(res);
EXPLANATION
var addX = inc => e => e + inc;
Is the equivalent of:
var addX = function(inc) {
return function(e) {
return e + inc;
}
}
So addX(2) returns the callback function(e) { return e + 2 } and it's the callback used by array.map

Related

How to create a composition from functions

I have 5 functions: func1(), func2(), func3(), func4(), func5(). I need to implement the compositionFunc() function, which can take any number of functions as arguments, and create a composition from them. The compositionFunc() function takes my 5 functions as arguments. The compositionFunc() function returns a function that takes its initial value as an argument. This nested function successively passing through an array of functions with each iteration returns the result of calling the accumulated value of the current function-argument. The result of one function can be passed as an argument to another function. How can i do this?
const func1 = (arg1) => {
return arg1;
};
const func2 = (arg2) => {
return arg2;
};
const func3 = (arg3) => {
return arg3;
};
const func4 = (arg4) => {
return arg4;
};
const func5 = (arg5) => {
return arg5;
};
const compositionFunc = () => {
...
};
you can define a function like this
const pipe = (...functions) => args => functions.reduce((res, f) => f(res), args)
const combine = (...functions) => args => functions.reduceRight((res, f) => f(res), args)
const plus1 = x => x + 1
const double = x => x * 2
const pipeFunction = pipe(plus1, double)
const combineFunction = combine(plus1, double)
console.log(combineFunction(1)) // (1 * 2) + 1
console.log(pipeFunction(1)) // (1 + 1) * 2
A simple reduce can accomplish that:
function pipe(input, ...func) {
return func.reduce((a, f) => f(a), input);
}
You pass it an initial value + chain of functions.
Example:
function f1(val) {
return val + 1;
}
function f2(val) {
return val * 10;
}
console.log(pipe(2, f1, f2)); //=> 30

How to implement sum(1)(2)(3) === 6 [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

How to call this default args function more than once?

I have encountered a question where I need to allow default args to be set on a function in JavaScript:
function dfltArgs(func, params) {
const strFn = func.toString()
console.log(strFn)
const args = /\(([^)]+)\)/.exec(strFn)[1].split(',')
const defaultVal = (arg, val) => typeof arg !== 'undefined' ? arg : val
return (...dynamicArgs) => {
const withDefaults = args.map((arg, i) =>
defaultVal(dynamicArgs[i], params[args[i]]))
return func(...withDefaults)
}
}
function add (a, b) { return a + b }
var add_ = dfltArgs(add,{b:9})
console.log(add_(10)) // Should be 19
var add_ = dfltArgs(add_,{b:3})
console.log(add_(10)) // Should now be 13
However, I need to be able to call this function more than once and overwrite previously set defaults:
var add_ = defaults(add,{b:9})
add_(10) // Should be 19
var add_ = defaultArguments(add_,{b:3})
add_(10) // Should now be 13
This does not work in my implementation, because the stringified function on the second call is: (...dynamicArgs) => {, etc.
How can I refactor this? Probably need to use bind somehow?
Instead of your complicated default args thing, why not just use some arrow functions with real default arguments:
var _add = (a, b = 8) => add(a, b);
That way you can easily change the bound things:
var add_ = (a = 2, b) => _add(a, b);
add_() // 10

piping functions in JavaScript

How can I have a JavaScript function let's say piper() which takes several functions as its arguments and it returns a new function that will pass its argument to the first function, then pass the result to the second, then
pass the result of the second to the third, and so on, finally returning the output of the last function.
Something like piper(foo, fee, faa)(10, 20, 30) would be equivalent to calling faa(fee(foo(10,20,30))).
ps:
It was a part of an interview, that I did few days ago.
For an arbritrary number of functions you could use this ES6 function:
function piper(...fs) {
return (...args) => fs.reduce((args,f) => [f.apply(this,args)],args)[0];
}
// Example call:
var result = piper(Math.min, Math.abs, Math.sqrt)(16, -9, 0)
// Output result:
console.log(result);
The same in ES5 syntax:
function piper(/* functions */) {
var fs = [].slice.apply(arguments);
return function (/* arguments */) {
return fs.reduce(function (args,f) {
return [f.apply(this,args)];
}.bind(this), [].slice.apply(arguments))[0];
}.bind(this);
}
// Example call:
var result = piper(Math.min, Math.abs, Math.sqrt)(16, -9, 0)
// Output result:
console.log(result);
Enjoy. Pure ES5 solution. Preserves this.
function piper(){
var i = arguments.length,
piped = arguments[ --i ];
while( --i >= 0 ){
piped = pipeTwo( arguments[ i ], piped );
}
return piped;
}
function pipeTwo( a, b ){
return function(){
return a.call( this, b.apply( this, arguments ) );
}
}
Or, if you want the fancy solution.
function piperES6( ...args ){
return args.reverse().reduce( pipeTwo );
}
Loops can be reversed depending on the desired direction.
Very similar to #trincot's answer (preserves context), but composes in the correct order and is marginally faster since it does not create intermediary arrays:
const piper = (...steps) => function(...arguments) {
let value = steps[0].apply(this, arguments);
for (let i = 1; i < steps.length; ++i) {
value = steps[i].call(this, value);
}
return value;
};
// Usage:
let p = piper(
x => x + 1,
x => x * 2,
x => x - 1
);
console.log(p(2)); // 5
Here is an alternative answer involving method chaining. I shall use ES6, though of course this can be transpiled to ES5. On benefit of this solution is that is has a very succinct TypeScript counterpart with perfect typeability.
class Pipe {
constructor(value) {
this.value = value;
}
then(f) {
return new Pipe(f(this.value));
}
}
const pipe = value => new Pipe(value);
// Example
const double = x => 2 * x;
pipe(42).then(double).then(console.log); // 84
const result = pipe(42).then(double).then(double).value;
console.log(result); // 168
A simple solution based on JS higher-order functions usage:
function pipe(...rest) {
return x => rest.reduce((y, f) => f(y), x);
}
Usage:
pipe((a) => a + 1, (a) => a * 2)(3) // 8
pipe((a) => a + 1, (a) => a * 2)(2) // 2
function f(f1, f2, f3){
return (args => f3(f2(f1(args))));
}
I think what you are trying to do is chaining.
var funct={
total:0,
add:function(a) {
console.log(funct.total,funct.total+a);
funct.total+=a;
return funct;
}
};
funct.add(5).add(6).add(9);

Currying a variadic function in JavaScript [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

Categories