javascript - Having trouble stepping through function that reduces an array of functions -


when using reduce method on array of functions having difficulty tracing through how reduce works on array exactly.

combofunc(num, functionsarr) {   return functionsarr.reduce(function (last, current) {     return current(last);   }, input); } 

so functionsarr = [add, multi] , functions add , multi being

function add(num) {   return num + 1; } 

and

function multi(num) {   return num * 30; } 

the function combofunc would:

combofunc(2, functionsarr); //returns 90; 

i understand how reduce method works on array of numbers folding array 1 value were, applying function each element of array. example combofunc taking array of functions parameter uses simple enough math can understand how reduce produces value of 90 mathematically don't understand happening line line , on each iteration functional level. i'm unable articulate in mind happening when---how input of 2 getting passed function function vis-a-vis closure , sequential firing off of each function, etc.

if reduce method applies function pass in each element of array, , when each element in array function...how can write out own understanding syntactically how looks?

the function passed reduce method returns current(last) that's function returning function. make last equal add function , current equal multi? in other words returning multi(add)? if logic correct, means happening input gets passed add , computed , returned value passed multi , computed return 90?

it looks you're trying create composition function takes array of functions apply input, num

let's first cover couple syntax errors. first you're missing function keyword

// code combofunc(num, functionsarr) {  // should function combofunc(num, functionsarr) { 

next, you've named parameter num reference input in function body

// code }, input);  // should }, num); 

so after fix this, function works, if approach problem little differently?

disclaimer: answer not walk through function you've provided. rather, sympathizes difficulty demonstrating combofunc written in overly complex way. in turn, give alternate definition of function operates identically lot easier read/understand.

to begin, think should go basics of function composition.

i picturing function composition little map.

  f(x)=y      g(y)=z +--------> y -------+ |                   | |                   | |                   v x ----------------> z           ? 

in example above, replace f add function, , g multi function. defining ? should obvious now.

  add(2)      multi(3) +--------> 3 -------+ |                   | |                   | |                   v 2 ----------------> 90   h(x) = g(f(x))  = z   h(x) = (g∘f)(x) = z   h(2)            = 90 

(g∘f) can said "g of f" , means apply x f first, apply result g.

notice y isn't present. we've defined h in terms of x gives direct "map" z, skipping on y entirely.

composing 2 functions basic operation, , define function easily

function comp(g,f) {   return function(x) {     return g(f(x));   } }  var h = comp(multi,add);     h(2);                   // 90 // h(2) = multi(add(2))    =  90 

"yeah, i'm trying work n functions. not 2."

ok, comp works 2 functions, i've on simplified problem. you're wondering how work if wanted compose 3, 4, or more functions together.

well let's @ again

a(w)              = x b(x)              = y c(y)              = z d(w) = c(b(a(w))) = z d(w) = (c∘b∘a)(w) = z 

look closely @ . know our comp function , can see appear between each of our functions, a, b, c.

before go further, let's have array of numbers

var xs = [1,2,3]; 

if want sum numbers, need call

var sum = 1 + 2 + 3 

see how + appears between each number? our array of functions, it's no different!

var fs = [c,b,a]; var d  = (c ∘ b ∘ a) 

we need make valid javascript. , it'll easy because we've defined comp.

this calling of function between terms in list called linear fold , javascript has function called reduce.

alright, let's put use! we'll fold ("reduce") our list of functions using our comp function

function compn(fs) {   return fs.reduce(comp); }  var h = compn([multi, add]);     h(2);                   // 90 // h(2) = multi(add(2))    =  90 // h(2) = (multi ∘ add)(2) =  90 

ok, works our original 2 functions, let's make sure works longer list

var = compn([multi, add, add, add]);     i(2);                               // 150 // i(2) = multi(add(add(add(2)))       =  150 // i(2) = (multi ∘ add ∘ add ∘ add)(2) =  150 

ok, let's recap

function add(num) {   return num + 1; }  function multi(num) {   return num * 30; }  function comp(g,f) {   return function(x) {     return g(f(x));   } }  function compn(fs) {   return fs.reduce(comp); }  compn([multi, add])(2); // 90 

"but why better?"

just cut out y in h(x) = (g∘f)(x) = z, notice how our compn function doesn't concern num, last, or current. we've dropped 3 variables our brain think , it's clearer our function doing.

comp takes f , g , composes them make g ∘ f.

compn calls comp between each term in list of functions

to me, straight forward , easy understand. looking @ function bodies each comp , compn, can identify intent immediately.

compare to

combofunc(num, functionsarr) {   return functionsarr.reduce(function (last, current) {     return current(last);   }, input); } 

it's no wonder had difficulty trying follow it. combofunc concerning onset because it's trying 2 operations instead of one.

so, know didn't step through original function, hope after reading answer have greater understanding of function composition , building own functions separated concerns.


edit

according discussion below, valuable our compn function work on empty array, [].

var f = compn([]); // uncaught typeerror: reduce of empty array no initial value 

yuck! intended behavior here compn create function returns unmodified input.

function id(x) {   return x; } 

using starting point reduce guarantee our compn function work when empty array given

// revised compn function compn(fs) {   return fs.reduce(comp, id); } 

check out

compn([])(2);           // 2 compn([multi, add])(2); // 90 

now compn work array of 0 or more functions.


Comments

Popular posts from this blog

c# - Validate object ID from GET to POST -

node.js - Custom Model Validator SailsJS -

php - Find a regex to take part of Email -