The minimum necessary change is that obj[a[j]]=count;
should be obj[s]=count;
, because you have that line running on every iteration of the inner loop regardless of whether j
refers to the letter you're currently tallying.
function countAllCharacters(str) {
var a = str.split("");
var obj = {};
a.forEach(function(s){
var count=0;
for(var j=0;j<a.length;j++){
if(s==a[j]){
count+=1;
}
obj[s]=count;
}
});
return obj;
}
console.log(countAllCharacters('banana'));
However, you don't need a nested loop. Your outer .forEach()
can update the count for the current letter directly:
function countAllCharacters(str) {
var a = str.split("");
var obj = {};
a.forEach(function(s){
obj[s] = (obj[s] || 0) + 1;
});
return obj;
}
console.log(countAllCharacters('banana'));
This can be made shorter with .reduce()
:
function countAllCharacters(str) {
return str.split("").reduce(function(obj, s){
obj[s] = (obj[s] || 0) + 1;
return obj;
}, {});
}
console.log(countAllCharacters('banana'));
Note that (obj[s] || 0)
means to use obj[s]
's value if it is truthy, otherwise use 0
. So the first time you encounter a particular letter obj[s]
will be undefined
, which is falsey, so then 0
will be used. The next time you encounter that letter obj[s]
will be 1
, which is truthy.