Reputation: 43
I have been struggling with why this won't work. We start as a {}, then grab the first element of the split string array. If that object property exists, then increase the value by one. If not, then create the property and set the value to 1. Any help would be really appreciated as I clearly am missing something about the reduce method.
const countCharacters = string => {
return string.split('').reduce((total, element) => {
if (total[element]) {
return total[element] += 1;
} else {return total[element] = 1}
},{});
};
Upvotes: 1
Views: 1264
Reputation: 1
If you want total
to be an Object in every iteration, you need to return the object from the previous iteration
Currently your code returns a Number = which isn't the Object you started with
Here's what happens with your code
'abca'.split('').reduce((total, element) => {
if (total[element]) {
return total[element] += 1;
} else {
return total[element] = 1;
}
},{});
first iteration .. total = {}, element = 'a', return total.a = 1 (which returns 1)
second iteration .. total = 1, element = 'b' ...
So, you want something like:
const countCharacters = string => {
return string.split('').reduce((total, element) => {
if (total[element]) {
total[element] += 1;
} else {total[element] = 1}
return total;
},{});
};
Or, more succinctly
const countCharacters = string => string.split('').reduce((total, element) => {
total[element] = (total[element] || 0) + 1;
return total;
}, {});
Or, less succinctly, but a one liner
const countCharacters = string => string.split('').reduce((total, element) => (total[element] = (total[element] || 0) + 1, total), {});
Upvotes: 2