Javascript function call with another function as parameter - javascript

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

Related

How to reuse a closure function assigning it to a variable or constant in JavaScript

I'm solving an exercise that is intended to use closures. You must create a function that returns a function that will store a value and, when you reuse it, add the new value to the saved one.
const firstValue = myFunction(3);
const secondValue = firstValue(4);
// result => 7
this is the code that I'm using to practice closures:
function addNumbers(num) {
let storage = 0
let n = num
function adding(n) {
storage += n;
return storage
}
return adding(n)
}
let firstAttemp = addNumbers(4)
let secondAttemp = firstAttemp(3)
console.log(firstAttemp)
this throw an error "Uncaught TypeError: firstAttemp is not a function"
const addNumbers = (a) => (b) => a + b
It's called currying, more details here.
P.S.
If you want to use function syntax, it will look like this:
function addNumbers(a) {
return function (b) {
return a + b
}
}
As #skara stated in their comment, return adding(n) returns the result of calling adding instead of returning the function so that it may be called later with firstAttemp(3).
Unfortunately though it still doesn't work because you don't actually assign the value passed to addNumber to be added later.
function addNumbers(num) {
let storage = 0;
let n = num;
function adding(n) {
storage += n;
return storage;
}
return adding;
}
let firstAttemp = addNumbers(4);
let secondAttemp = firstAttemp(3);
console.log(firstAttemp);
console.log(secondAttemp); // 3! 😢
You don't actually need to manually save the value of num to a variable as it is captured in the closure arround adding that is being returned.
function addNumbers(num) {
function adding(n) {
return num + n;
return storage;
}
return adding;
}
let firstAttemp = addNumbers(4);
let secondAttemp = firstAttemp(3);
console.log(secondAttemp); // 7 👍🏻

Apparently simple function not returning anything

I'm sure I'm just having a moment, but I can't figure this out for anything. I wanted to create a quick function to sum up a particular JSON object's values over an array, but it returns nothing. Here's the code:
var a=[{"b":"23"},{"b":"37"}]
function sumJSON(json,elem){
var total=0;
$.each(json,function(index,item){
var count=index+1;
total+=Number(item[elem]);
if(count===json.length){
return total;
}
})
}
console.log(sumJSON(a,"b"));
Here's the jsfiddle
Just in case you want this to be solved with plain javascript.
var a = [{"b":"23"},{"b":"37"}]
function sumJSON(a,key) {
return a.reduce((s, data) => s + (+data[key]), 0)
}
console.log(sumJSON(a, 'b'))
var a=[{"b":"23"},{"b":"37"}]
function sumJSON(json,elem){
var total=0;
$.each(json,function(index,item){
total+=Number(item[elem]);
})
return total;
}
console.log(sumJSON(a,"b"));
$each needs not to return anything, just calls a function for each member of the collection, you need to return the total after the call to $.each, once the function has been called for all the elements

I'm trying to rewrite memoize in javascript (for underscore), can someone explain this?

I know that the purpose of memoize is to cache values so code can be run faster by not having to re-calculate the same answer everytime. My issue stems from returning a function (i think). The google chrome debugger isn't that useful for me here because everytime I try to run this memoize function, it just goes from the argus variable (on line 4 i believe) all the way down to the semi-colon. Furthermore, result always returns an empty object instead of storing a value in result.
I start by defining a function:
function add(a,b){
return a+b;
}
This is my attempt at the memoize function:
_.memoize = function(func) {
var result = {};
var flag = 0;
var argus = Array.prototype.slice.call(arguments)
return function() {
if(result[key] === arguments){
flag = 1
}
else if(flag = 0){
result[argus] = func.apply(this, argus);
}
return result[argus];
};
};
I'd call memoize by doing _.memoize(add(2,5)) but the result doesn't get stored in the result object.
Am I even close to getting this memoize function working properly? Any guidance you guys can give here would be appreciated.
The biggest point you're missing is that _.memoize is called on the function first, and it returns a new function. You are calling it on the result of a function call (which is the number 7 in this case).
In order to get it to work, you need to rearrange a few things.
Also note that it's not wise to try to use an array itself as the index to an object. One approach to get around that would be to convert the arguments array to JSON and use that as the index on the results object:
function add(a, b) {
console.log('Called add(' + a + ', ' + b + ')');
return a + b;
}
var _ = {};
_.memoize = function(func) {
var results = {};
return function() {
var args = Array.prototype.slice.call(arguments);
var key = JSON.stringify(args);
if (!(key in results)) {
results[key] = func.apply(this, args);
}
return results[key];
};
};
var madd = _.memoize(add);
console.log(madd(2, 4));
console.log(madd(9, 7));
console.log(madd(2, 4));

Passing a function as argument which uses the argument of parent function but also has it's own argument

I just started playing around with functional programming and am trying to pass a function as an argument of another function. However the function that I am trying to pass also has arguments like so:
function splitStringBy(string, type, func) {
// Split string by type.
var splitArray = string.split(type);
console.log(splitArray);
// Do something with the array.
func !== undefined ? func(splitArray) : null;
}
function loopArray(array, func) {
// Loop through array.
for (var i = 0; i < array.length; i++) {
func(array[i]);
}
}
I need to pass splitArray to my loopArray()
Here's how I'm trying to call it:
splitStringBy($scope.textSpace, "<br>", loopArray(splitArray, function() {
console.log('It worked!');
}));
Console comes up with Error: splitArray is not defined.
Rather than passing loopArray as a function, you're actually calling it, then passing its return value to splitStringBy. Since splitArray isn't defined when you first reference it, it's throwing that error.
What you want to do is something like this:
function splitStringBy(string, type, func) {
// Split string by type.
var splitArray = string.split(type);
console.log(splitArray);
// Do something with the array.
func !== undefined ? func(splitArray) : null;
}
function loopArray(func) {
// Return function for looping.
return function(array) {
// Loop through array.
for (var i = 0; i < array.length; i++) {
func(array[i]);
}
}
}
splitStringBy($scope.textSpace, "<br>", loopArray(function() {
console.log('It worked!');
}));
This is called currying, where a function passes a function as a return value. loopArray will create a function, then return it. We then pass the newly made function to splitStringBy, which then invokes it.

How argument is being passed in the function(which itself is an argument) in JavaScript

I have a very basic question about JavaScript.
Consider the following code:
var numbers = [4,2,3,4,5,4,3,2,1];
var everyResult = numbers.every(function(item,index,array) {
alert(arguments.length);
return (item > 1);
});
Now in the above code I am passing anonymous function as an argument of "every" function.
How exactly my anonymous function is getting the exactly 3 arguments(item,index,array).
This isn't really a basic javascript question, but a library question, and how it "happens" depends on the implementation.
This here is a sample implementation of every in javascript:
function every(array, fn) {
for(var i = 0; i < array.length; i++) {
fn(array[i], i, array);
}
}
You would call it like this:
every([1,2,3,4], function(item, index, array) {
// do stuff
});
As you can see, it's the every function itself, that calls the fn (which is the function you pass in), and decides what arguments to pass.
The anonymous function you're passing is simply provided as argument for every() method which calls it for a number of times. every() iterates through your list items and calls your anonymous function each time with three arguments: value, index and your entire array.
Here's an approximate source code of how the actual every() function works:
Array.prototype.every = function(callback) {
for(i=0; i<this.length; i++) {
callback(this[i], i, this);
}
}
Let's build a simple function with a callback argument:
function foo(callback)
{
var callbackArgument = 'bar';
callback(callbackArgument);
}
Let's use it:
foo(function(arg){
console.log(arg);
}); // logs "bar" to the console!
How exactly my anonymous function is getting the exactly 3
arguments(item,index,array)?
Maybe it would be easier to understand with an alternative example You have:
var numbers = [4,2,3,4,5,4,3,2,1];
var everyResult = numbers.every(function(item,index,array) {
alert(arguments.length);
return (item > 1);
});
You could also write the same in the following manner:
var numbers = [4,2,3,4,5,4,3,2,1];
var everyResult = numbers.every(item,index,array) {
function anonymous(firstVar,secondVar,thirdVar){
//do your anonymous stuff here
alert(thirdVar.length);
return (firstVar > 1);
}
//get the anonymous function processed data
var anonymousFunctionResults = anonymous(item,index,array);
//do your original stuff that you would have done with the results of anonymous function
anonymousFunctionResults...
}
});
Or in this way:
function anonymous(firstVar,secondVar,thirdVar){
//do your anonymous stuff here
alert(thirdVar.length);
return (firstVar > 1);
}
var numbers = [4,2,3,4,5,4,3,2,1];
var everyResult = numbers.every(item,index,array, anonymous) {
//get the anonymous function processed data
var anonymousFunctionResults = anonymous(item,index,array);
//do your original stuff that you would have done with the results of anonymous function
anonymousFunctionResults...
}
});
Or in this way:
function anonymous(firstVar,secondVar,thirdVar){
//do your anonymous stuff here
alert(thirdVar.length);
return (firstVar > 1);
}
var numbers = [4,2,3,4,5,4,3,2,1];
var everyResult = numbers.every(anonymous(item,index,array)) {
//get the anonymous function processed data
//you can use the "firstParameter" variable already of course
//this is just to make a point
var anonymousFunctionResults = firstParameter;
//do your original stuff that you would have done with the results of anonymous function
anonymousFunctionResults...
}
});
If I understood your question well :)

Categories