2017-04-25 2 views
1

Ich versuche, Javascript reduzieren mit einer rekursiven Funktion zu reduzieren. Hier ist mein Versuch, der nicht funktioniert. Wenn jemand es nur leicht ändern kann, damit es funktioniert, wäre das großartig, weil ich es besser verstehen würde. (Dies ist eine Übung in functional-javascript-workshop).Warum ist diese rekursive Definition von reduce working (JS) nicht?

function reduce(arr, fn, initial) { 
    if (arr.length) { 
    var newArr = arr.slice(1, arr.length); 
    return reduce(newArr, fn, fn(arr[0])); 
    } else { 
    return initial; 
    } 
} 

module.exports = reduce 

Es gibt mir die folgende kryptische Fehlermeldung, die ich weiß nicht, wie zu interpretieren:

/usr/local/lib/node_modules/functional-javascript-workshop/exercises/basic_recursion/exercise.js:13 
    prev[curr] = ++prev[curr] || 1 
          ^

TypeError: Cannot create property 'undefined' on string 'exercitation' 
    at /usr/local/lib/node_modules/functional-javascript-workshop/exercises/basic_recursion/exercise.js:13:29 
    at reduce (/home/david/node-school/functional-workshop/solution.js:7:28) 
    at /usr/local/lib/node_modules/functional-javascript-workshop/exercises/basic_recursion/exercise.js:12:10 
    at obtainResult (/usr/local/lib/node_modules/functional-javascript-workshop/exercises/runner.js:100:21) 
    at Exercise.<anonymous> (/usr/local/lib/node_modules/functional-javascript-workshop/exercises/runner.js:66:27) 
    at next (/usr/local/lib/node_modules/functional-javascript-workshop/node_modules/workshopper-exercise/exercise.js:188:19) 
    at /usr/local/lib/node_modules/functional-javascript-workshop/node_modules/workshopper-exercise/exercise.js:195:7 
    at Exercise.<anonymous> (/usr/local/lib/node_modules/functional-javascript-workshop/exercises/runner.js:34:5) 
    at next (/usr/local/lib/node_modules/functional-javascript-workshop/node_modules/workshopper-exercise/exercise.js:188:19) 
    at /usr/local/lib/node_modules/functional-javascript-workshop/node_modules/workshopper-exercise/exercise.js:195:7 
+0

Ich frage mich nur: funktioniert 'if (arr.length)'? Ich benutze immer 'if (arr.length> 0)' ... – Danmoreng

+2

Sie zeigen uns nicht den richtigen Code. Der Fehler tritt in "exercise.js" auf, nachdem er in Zeile 7 in "solution.js" aufgerufen wurde. –

+1

@Danmoreng, testet den Truthy-Wert –

Antwort

6

Sie müssen den Speicher aktualisieren:

function reduce(arr, fn, acc) { 
 
    if (arr.length) { 
 
    var newArr = arr.slice(1, arr.length); 
 
    acc = fn(arr[0], acc) 
 
    return reduce(newArr, fn, acc); 
 
    } else { 
 
    return acc; 
 
    } 
 
} 
 

 
console.log(reduce([1,2,3], (val, sum) => sum + val, 0))

+2

Das ist nur, wie Ihre Meinung Mann. (Danke!) –

+1

der Kerl bleibt – thedude

+0

Ich habe dich gewählt, nur weil du El Duderino bist – Greeso

2

Sie haben vergessen, den aktuellen Wert der acc zu übergeben Umsetzer, d.h. initial, in den fn Anruf.

0

Wie andere bemerkt haben, haben Sie es versäumt, den Akkumulator an fn zu übergeben. Wenn Sie neugierig sind, reduce kann in einem einzigen ternären (?:) Ausdruck ausgedrückt werden - auch, arr.slice(1) wird von 1 bis zum Ende des Arrays schneiden; es gibt keine Notwendigkeit, das Ende der Scheibe in diesem Fall

const reduce = (arr, fn, acc) => 
 
    arr.length === 0 
 
    ? acc 
 
    : reduce(arr.slice(1), fn, fn(acc, arr[0])) 
 

 
const add = (x,y) => x + y 
 

 
console.log(reduce([1,2,3], add, 0)) // 6

Da arr.length === 0, arr.slice(1) und arr[1] sind so häufig in funktionalem Code Umgang mit Arrays angeben, ist es üblich, diese abstrahiert in Funktionen zu sehen Komplexität und kognitive Belastung zu reduzieren

// isEmpty :: [a] -> Boolean 
 
const isEmpty = arr => arr.length === 0 
 

 
// head :: [a] -> a 
 
const head = arr => arr[0] 
 

 
// tail :: [a] -> [a] 
 
const tail = arr => arr.slice(1) 
 

 
// reduce :: ([a], ((b, a) -> b), b) -> b 
 
const reduce = (arr, fn, acc) => 
 
    isEmpty(arr) 
 
    ? acc 
 
    : reduce(tail(arr), fn, fn(acc, head(arr))) 
 

 
// add :: (Number, Number) -> Number 
 
const add = (x,y) => x + y 
 

 
console.log(reduce([1,2,3], add, 0)) // 6

Verwandte Themen