Reputation: 53
I have n number of functions, each one takes a 'data' {Object} as argument. Each function return a {Boolean} based on the given argument.
I want to compose/chain these functions, what is the best way to accomplish that?
See code below.
var fn1 = function(data) {
return data.status === 404;
};
var fn2 = function(data) {
return data.url === 'any_url';
};
var composed = compose(fn1, fn2);
// The line below must return false:
composed({ status: 404, url: 'foobar'});
// The line below must return true:
composed({ status: 404, url: 'any_url'});
Upvotes: 2
Views: 531
Reputation: 17906
you could do something as simple as
function compose(data){
return fn1(data) && fn2(data)
}
this function will return true if all conditions(return values of your functions) are true
Upvotes: 0
Reputation: 816522
So you want to return true
if all functions return true
? That can be achieved with Array#every
. We simply use Array#every
on the array of functions and return the function's result in the callback:
function compose() {
var fns = Array.prototype.slice.call(arguments);
return function(obj) {
return fns.every(function(f) {
return f(obj);
});
};
}
function compose() {
var fns = Array.prototype.slice.call(arguments);
return function(obj) {
return fns.every(function(f) {
return f(obj);
});
};
}
var fn1 = function(data) {
return data.status === 404;
};
var fn2 = function(data) {
return data.url === 'any_url';
};
var composed = compose(fn1, fn2);
// The line below must return false:
console.log(composed({
status: 404,
url: 'foobar'
}));
// The line below must return true:
console.log(composed({
status: 404,
url: 'any_url'
}));
The advantage of this is that Array#every
will stop as soon as one return value is false
.
With ES6+:
function compose(...fns) {
return obj => fns.every(f => f(obj));
}
Note: compose
is a poor choice of name for this because "composing functions" usually refers to passing the result of one function into the other function. I.e. compose(f, g)(x)
would be the same as f(g(x))
.
Upvotes: 4