How would I create an invert higher order function? - javascript

I need to create a higher-order function called invert. It should do the following:
Return a new function.
Take a function as its only argument.
The inner function should take any number of arguments and inverts a call to the passed function.
What I have so far is just http://prntscr.com/l0rma0 but it only works for functions with no arguments.

Hopefully, this should be enough:
function invert(fn) {
return (...args) => !fn(...args);
}
Here's the test case:
function invert(fn) {
return (...args) => !fn(...args);
}
// test 1
const returnsTrue = () => true;
const returnsFalse = invert(returnsTrue);
console.log( returnsFalse() === false );
// test 2
const isEven = x => x % 2 === 0;
const isOdd = invert(isEven);
console.log( isOdd(13) === true );
console.log( isOdd(10) === false );
// test 3
const isSumBiggerThan100 = (...args) => args.reduce((acc, val) => acc + val) > 100;
const isSumLessThanOrEqualTo100 = invert(isSumBiggerThan100);
console.log( isSumLessThanOrEqualTo100(10, 3, 8, 5, 4, 20) === true);
console.log( isSumLessThanOrEqualTo100(70, 10, 50, 23) === false)

const higherFunction = (something) => {
return function innerFunc(...params) {
return !something;
}
};
Do you mean something like that ?

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 I can reset variable value when function end?

I have such function and global variable (as array):
const arraysList = []
export const changeColorCategories = (array, draggedColumnId) => {
const isColor = arraysList.length ? arraysList[0][0]?.color : [];
if (typeof isColor === 'string') {
firstLevelColor = isColor;
}
return array.map((item, index, categories) => {
item.color = draggedColumnId !== 3 ? '#010172' : '#000000';
arraysList.push(categories);
if (firstLevelColor && !draggedColumnId) {
item.color = firstLevelColor;
}
if (item?.children?.length) {
changeColorCategories(item.children);
}
return item;
})
}
Every call of this function push some data to array. In this function I use recursion. So how i can clear this array only when this function will end it's work.
You can call the recursion function inside another function this way you can run anything you want when the function ends
const arraysList = []
export const changeColorCategories = (array, draggedColumnId) => {
const isColor = arraysList.length ? arraysList[0][0]?.color : [];
if (typeof isColor === 'string') {
firstLevelColor = isColor;
}
return array.map((item, index, categories) => {
item.color = draggedColumnId !== 3 ? '#010172' : '#000000';
arraysList.push(categories);
if (firstLevelColor && !draggedColumnId) {
item.color = firstLevelColor;
}
if (item?.children?.length) {
changeColorCategories(item.children);
}
return item;
})
}
function runRucFunc(){
const result = changeColorCategories();
//Your other code goes here
return result;
}
You can just put your recursion part inside a sub function.
Below I've called the inner function inner, I've also moved the arrayList into the function, due to closures you wound't even need to clear the arrayList, it would be cleared automatically as it goes out of scope.
eg.
export const changeColorCategories = (array, draggedColumnId) => {
const arraysList = []
function inner(array, draggedColumnId) {
const isColor = arraysList.length ? arraysList[0][0]?.color : [];
if (typeof isColor === 'string') {
firstLevelColor = isColor;
}
return array.map((item, index, categories) => {
item.color = draggedColumnId !== 3 ? '#010172' : '#000000';
arraysList.push(categories);
if (firstLevelColor && !draggedColumnId) {
item.color = firstLevelColor;
}
if (item?.children?.length) {
inner(item.children); //we call inner here instead.
}
return item;
})
}
// now call our inner
// you could do something even before your recursion.
const result = inner(array, draggedColumnId);
// here we can put what we want after recursion.
return result;
}
You could wrap the recursive call in another function like so:
const arr = []
const recursive = (counter = 0) => {
if(counter === 5)
return arr.map((v) => String.fromCodePoint(65 + v))
arr.push(counter)
return recursive(++counter)
}
const go = () => {
console.log(recursive()) // [A,B,C,D,E]
console.log(arr) // [0,1,2,3,4]
arr.length = 0 // clear the array
console.log(arr) // []
}
go()
Alternatively, if the global array does not actually need to be global, and is merely a container for working information of the recursive algorithm, then you could make it a parameter of the recursive function, which will then fall out of scope (and be garbage collected) when the recursion ends.
const recursive = (counter = 0, arr = []) => {
if(counter === 5)
return arr.map((v) => String.fromCodePoint(65 + v))
arr.push(counter)
return recursive(++counter, arr)
}
console.log(recursive()) // [A,B,C,D,E]
console.log(arr) // Error! Not in scope!
go()
Or, you could make the recursive function more intelligent and able to detect when it is processing the final recursion: how this is done will depend on the precise logic of the recursive function.

Add console log in an one arrow (auto return) function without adding curly braces

So consider you have a one line auto return arrow function:
const test = (val) => val;
How would you check the val without doing:
const test = (val) => {
console.log(val);
return val;
};
You can actually use || between the arrow function and the returned value like so:
const test = (val) => console.log(val) || val;
This will not interfere with the process and will also log val without the hassle of adding {} and return and undoing it once you're done
echo is a great function for this -
const echo = (x) =>
( console.log(x)
, x
)
const test = x => echo(x) + 1
const arr = [ 1, 2, 3 ]
const result = arr.map(test)
console.log(result)
Arrow functions are a functional style. Utilising functional techniques will make it more enjoyable to work with arrow expressions -
const effect = f => x =>
(f(x), x)
const echo =
effect(console.log)
const test = x => echo(x + 1) // <-- wrap echo around anything
const arr = [ 1, 2, 3 ]
const result = arr.map(test)
console.log(result)
// 2
// 3
// 4
// [ 2, 3, 4 ]
You can use echof to wrap an entire function, such as echof(test) -
const effect = f => x =>
(f(x), x)
const comp = (f, g) =>
x => f(g(x))
const echo =
effect(console.log)
const echof = f =>
comp(echo, f)
const test = x => x * x
const arr = [ 1, 2, 3 ]
const result = arr.map(echof(test)) // <-- echof
console.log(result)
// 1
// 4
// 9
// [ 1, 4, 9 ]

returning object that returns functions

I need to write a function in JavaScript that takes a number and returns an object that returns chainable functions (without using OOP).
Example:
func(3).not().not().equals(4)
would outputs false.
And:
func(5).equals(5)
would output: true
This is the code I have written:
const func = (obj) => {
const obj2 = {
not: () => {
return !obj
},
equals: (num) => {
return obj === num
}
}
return obj2
}
It works when I call func(3).not() or func(5).equals(5), but doesn't allow me to chain the functions so calling func(5).not().equals(5) returns an error saying that this is not a function.
What am I not seeing here?
That's a very weird way to compose functions. Let's think about what's actually happening.
func(3).not().not().equals(4)
// is equivalent to
not(not(equals(4)(3)))
// where
const not = x => !x;
const equals = x => y => x === y;
The simplest way to implement this chain would be as follows.
const equals = x => toBool(y => x === y);
const toBool = func => ({
not: () => toBool(x => !func(x)),
func
});
const example1 = equals(4).not().not().func(3);
const example2 = equals(5).func(5);
console.log(example1); // false
console.log(example2); // true
However, this is a forward chain. You want a backward chain. Unfortunately, there's a problem.
In a forward chain .func(x) marks the end of the chain.
In a backward chain .equals(x) marks the end of the chain.
This means that in a backward chain, you wouldn't be able to write the following expression.
func(3).not().not().equals(4).add(1)
// expected to be equivalent to
not(not(equals(4)(add(1)(3))))
// but actually equivalent to
not(not(equals(4)(3))).add(1)
// which evaluates to
false.add(1)
On the other hand, you would be able to do this quite easily using a forward chain.
const id = x => x;
const toNum = func => ({
add: x => toNum(y => x + func(y)),
equals: x => toBool(y => x === func(y)),
func
});
const toBool = func => ({
not: () => toBool(x => !func(x)),
func
});
const { add, equals } = toNum(id);
const example1 = equals(4).not().not().func(3);
const example2 = add(1).equals(4).not().not().func(3);
console.log(example1); // false
console.log(example2); // true
By the way, this is an object-oriented design pattern even though it doesn't make use of classes.
My advice would be to write plain old functions.
const add = (x, y) => x + y;
const equals = (x, y) => x === y;
const not = x => !x;
const example1 = not(not(equals(4, 3)));
const example2 = not(not(equals(4, add(1, 3))));
console.log(example1); // false
console.log(example2); // true
The simplest solutions are usually the best. Source: Occam's razor.
To return another object with the same methods that wraps the new value, simply call func again:
const func = (obj) => {
const obj2 = {
not: () => {
return func(!obj)
// ^^^^^^^^^^^^^^^^^
},
equals: (num) => {
return obj === num
}
}
return obj2
}
console.log(func(3).not().not().equals(4))
console.log(func(5).equals(5))
console.log(func(3).not())
You can use a closure to store both the initial input and the state of the operation:
const func = (input) => {
let not = false
const obj = {
not: () => {
not = !not
return obj
},
equals: (num) => {
return not ? input !== num : input === num
}
}
return obj;
}
console.log(func(5).not().equals(5))
console.log(func(5).not().not().equals(5))
console.log(func(5).not().equals(4))
console.log(func(5).not().not().equals(4))
You could take an object for return as interface and store value and negation.
var object = {
func: function (value) {
object.left = value;
return object;
},
not: function() {
object.negation = !object.negation;
return object;
},
equals: function (value) {
var result = value === object.value;
return object.negation ? !result : result;
}
},
func = object.func;
console.log(func(3).not().not().equals(4));

Categories