jamie jamie - 15 days ago 7
Javascript Question

Can't get this reduce function to work

Working through

Eloquent JavaScript and High Order Functions
- section in
Functional Programming
.

Trying to define a
reduce
function and use it in a higher order function
countWords();
, which takes a given array and counts number of times each particular value is present and puts it in an object.

I.e. this works:

function combine(countMap, word) {
countMap[word] = ++countMap[word] || 1; // made the edit

return countMap;
}

function countWords(wordArray) {
return wordArray.reduce(combine, {});
}

var inputWords = ['Apple', 'Banana', 'Apple', 'Pear', 'Pear', 'Pear'];

countWords(inputWords); // {Apple: 2, Banana: 1, Pear: 3}


I.e. this does not:

function combine(countMap, word) {
countMap[word] = ++countMap[word] || 1;

return countMap;
}

function forEach(array, action) {
for (var i = 0; i < array.length; i++) {
action(array[i]);
}
}

function reduce(fn, base, array) {
forEach(array, function (element) {
base = fn(base, element);
});

return base;
}

function countWords(wordArray) {
return reduce(combine, {}, wordArray);
}

var inputWords = ['Apple', 'Banana', 'Apple', 'Pear', 'Pear', 'Pear'];

countWords(inputWords); // returned this - [object Object] { ... } - this is no longer an issue after fix keeping it noted for reference to the original issue.


Any help on this would be great. Thanks.

Answer

The reason is that your ForEach implementation is wrong. you should set i = 0;

function forEach(array, action) {
    for(var i = 0; i < array.length; i++) {
        action(array[i]);
    }   
}

There seems to be something wrong. You update an object. ++countMap

function combine(countMap, word) {
    countMap[word] = ++countMap || 1;
    return countMap; 
}

It should be

function combine(countMap, word) {
    countMap[word] = ++countMap[word] || 1;
    return countMap; 
}

I add a jsbin here

Comments