Counting all characters in a string

advertisements

I want to count all characters in a string and return it to an object. I have tried but I’m unable to get the correct answer.

This is my code:

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[a[j]]=count;
    }
  });
  return obj;
}
console.log(countAllCharacters('banana'));

Output:

{ b: 0, a: 3, n: 2 }

Which obviously is wrong.

Can anyone help me with that? Where I am going wrong?


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.