Javascript array of functions: Pass each function as parameter to another function - javascript

I have a usercase where I get an array of functions from backend something like:
var arr = [A(){}, B(){}, C(){}];
Now I need a way to execute them such that each function in the array is passed as a parameter to another function in the array.
A(B(C()));

I'm curious how you managed to get the functions from the back-end, but it doesn't matter for your question, so here goes your answer:
var arr = [A(){}, B(){}, C(){}];
var value = arr[arr.length - 1]();
for (var i = arr.length - 2; i >= 0; i--) {
value = arr[i](value);
}
console.log(value);

You can use Array.prototype.reduce to execute consecutive calls to a list of functions.
Update: As ASDFGerte suggests, you can use reduceRight instead of reduce to reverse the function execution flow.
const text = 'That will be 3.50';
const funcList = [extractNumber, parseNumeric, formatCurrency];
console.log('Parsed:', chainFunctions(funcList, text));
console.log('Parsed:', chainFunctionsReverse(funcList.reverse(), text));
function chainFunctions(funcList, startingValue) {
return funcList.reduce((result, func) => func(result), startingValue);
}
function chainFunctionsReverse(funcList, startingValue) {
return funcList.reduceRight((result, func) => func(result), startingValue);
}
function extractNumber(str) {
return str.match(/\b(\d+(\.\d+)?\b)/)[1];
}
function parseNumeric(numStr) {
return parseFloat(numStr);
}
function formatCurrency(num) {
return `$${num.toFixed(2)}`;
}
.as-console-wrapper { top: 0; max-height: 100% !important; }

Related

How this parameter knows the argument

Im confused with how the elem get the value of arr?
function lengGreaterThan(num) {
function lengGreaterThanNum(elem) {
return elem.length > num;
}
return lengGreaterThanNum;
}
let arr = ['Justin', 'caterpillar', 'openhome'];
console.log(arr.filter(lengGreaterThan(6)));
That is a really confusing way of writing it, but essentially you are just putting a function that takes one parameter into the filter function.
This here would do the same thing:
console.log(arr.filter((elem) => {
return elem.length > 6;
}));

Passing function to map

I was trying to understand this simple code snippet
function fnWrapper (fn) {
return function printResults (...args) {
const results = args.map(fn)
console.log(results)
}
}
const squarePrinter = fnWrapper(x => x*x)
const cubePrinter = fnWrapper(x => x*x*x)
const nums = [1, 2]
squarePrinter(1, 2)
cubePrinter(1, 2)
While, almost everything make sense, I am unable to comprehend this part args.map(fn)
i.e map should give an element but how are we able to pass our fn function and getting the desired result directly
As per map documentation it takes callback function as parameter and returns A new array with each element being the result of the callback function.
For example
var new_array = arr.map(function callback(currentValue[, index[, array]]) {
// Return element for new_array
}[, thisArg])
So in your case
squarePrinter(1, 2)
const results = args.map(fn)
is equivalent to
const results = [1, 2].map(function(x) {
return x*x;
})
map function takes a callback function, which gets executed with the array elements on each iteration.
You might think of the above code like
args.map((x) => x*x);
which is nothing but the fn function provided as argument to the fnWrapper
A typical implementation of map would be something like
Array.prototype.map = function (callback) {
const resultArray = [];
for (let index = 0; index < this.length; index++) {
resultArray.push(callback(this[index], index, this));
}
return resultArray;
}
args.map(fn) will take each argument and perform the operations on those arguments to create a new list.
More Like
squarePrinter(1, 2) => [1,2].map(x => x*x)
Map is a higher order function which can take callback function as argument, in simple form map() implementation would seem like this:
Array.prototype.myMap = function(callback) {
arr = [];
for (let i = 0; i < this.length; i++)
//Map function take 3 parameter: the item, items's index and the array it self
arr.push(callback(this[i], i, this));
return arr;
};

Recursive javascript function returns undefined [duplicate]

For some reason the method getTwo() inside the PollClass won't return 2 but undefined. If I put the return statement outside the .forEach() loop a value does get returned however.
class Poll {
constructor(name) {
this.name = name;
this.nums = [1, 2, 3];
}
getTwo() {
this.nums.forEach(num => {
if (num === 2) return num;
})
}
}
const newPoll = new Poll('random name');
console.log(newPoll.getTwo()); // returns undefined, not 2
Is this an issue with closure, ES 6, or a whole other issue?
An arrow function is still a function, and you're only returning from the forEach callback function, not from getTwo, you have to return from the getTwo function as well.
It's not quite clear why you would use a loop to check for something in that way, but the concept would be something like
getTwo() {
var n = 0;
this.nums.forEach(num => {
if (num === 2) n = num;
})
return n; // returns something from getTwo()
}
As adeneo mentioned, you must return from the getTwo function to achieve what you want. Returning from the callback passed into forEach, regardless if its an arrow function or not, doesn't return from forEach itself.
Alternatively to forEach, you can use find which you can write in less code and return directly:
getTwo() {
return this.nums.find(num => num === 2);
}

JSFiddle & Callbacks

As part of an exericse, I'm re-writing underscore functions and testing them in jsfiddle. Every time I pass a callback function, I get "undefined".
My code is below:
each = function(collection, iterator) {
if(Array.isArray(collection)){
for (var i = 0; i < collection.length; i++) {
iterator(collection[i], i, collection);
}
} else {
for(var key in collection) {
iterator(collection[key], key, collection);
}
}
};
var numbers = [1,2,3,4];
var result = each(numbers, function(num) {
return num * 2;
});
console.log(result);
// undefined
Any idea what I'm doing wrong and why it's not outputting on jsfiddle?
You aren't doing anything wrong. Your each function isn't returning anything. This is fine, since each functions don't necessarily have to return anything. You might be thinking along the lines of a map or reduce function which compile the results of calling the callback on each item in the collection, and then return that compilation.
The callback you pass to an each function doesn't normally return anything. Think of an each like it's just syntactic sugar for a normal for loop; for loops don't return anything (obviously..), they just perform generic operations with the items in the collection and the variables that have been declared in the containing scope.
That being said, if you want to emulate underscore (or any good library), you will want to return the collection to enable chaining. From the underscore docs:
[each] Iterates over a list of elements, yielding each in turn to an iteratee function....Returns the list for chaining.
This is just good practice so as to avoid annoying the developers who may use your library and are used to being able to chain everything in JavaScript.
So all you'd need to do is put
return collection;
at the end of your each function and you're good. Cheers.
You are not aggregating the result of your operation that's why the result is not being result.
Here is a quick stab at how this can be fixed for arrays.
each = function(collection, iterator) {
var arr = [];
if(Array.isArray(collection)){
for (var i = 0; i < collection.length; i++) {
arr.push( iterator(collection[i], i, collection) );
}
return arr;
} else {
for(var key in collection) {
iterator(collection[key], key, collection);
}
}
};
var numbers = [1,2,3,4];
var result = each(numbers, function(num) {
return num * 2;
});
console.log(result);
jsfiddle

Javascript function call with another function as parameter

I have a few functions in two different files that are all linked together by function calls they are as follows
FILE 1:
function getFunction(func){
}
FILE 2:
function Numbers(one, two) {
return (one*two);
}
var func = getFunction(Numbers);
and these are called by:
func(input_array);
my array has values 1,3,5,7,9 and I need func(input_array) to return 3,15,35,63,9 (the last value loops back to the first value)
basically what I am trying to do is have getFunction return a function such that these values are calculated. I am having trouble because I can't wrap my mind about sending and returning functions. I don't know how to access the array if it isn't sent into the function. Let me know if I need to clarify anything.
function getFunction(callback) {
return function(array) {
return array.map(function(cur, index) {
return callback(cur, array[(index+1) % array.length]);
});
};
}
getFunction returns a closure over the callback parameter, which is the function that you want to call. The closure receives the array parameter, and it calls the callback in a loop over the array using array.map. The % modulus operator performs the wraparound that you want.
Another way to write this that may be clearer is:
function getFunction(callback) {
return function(array) {
var result = [];
for (var i = 0; i < array.length; i++) {
j = (i+1) % array.length; // Next index, wrapping around
result.push(callback(array[i], array[j]));
}
return result;
};
}
var func = getFunction(Numbers);
console.log(func([1,3,5,7,9])); // Logs [3,15,35,63,9]
here is simple function that returns what you need
function Numbers(x) {
output_array=[];
for(i=0;i<x.length;i++){
if(x[i+1]==undefined){
output_array.push(x[i]);
}
else{
output_array.push(x[i]*x[i+1]);
}
}
return output_array;
}
var input_array=[1,3,5,7];
var num = Numbers(input_array);
console.log(num);
OR if you need it in the way function calling another function
and than returning the result use this
function getFunction(Numbers,input_array){
return Numbers(input_array);
}
function Numbers(x) {
output_array=[];
for(i=0;i<x.length;i++){
if(x[i+1]==undefined){
output_array.push(x[i]);
}
else{
output_array.push(x[i]*x[i+1]);
}
}
return output_array;
}
var input_array=[1,3,5,7];
var num = getFunction(Numbers,input_array);
console.log(num);

Categories