0

"Write a JavaScript function to get the number of occurrences of each letter in specified string." I've tried this way, but all my outputs are 0 and I really don't get why.

My idea was: Alphabetic order - so if one letter is the same with the next one, the counter increases. When it isn't the same, it logs the letter, how many times it appears and it resets the counter.

By the way, I don't know how to make it read the letters which appear only once. Can you help?

function count(string) {
  let string1 = string.split("").sort().join("");
  let counter = 0;
  for (let i = 0; i < string.length; i++) {
    if (string1[i] == string[i + 1]) {
      counter++;
    } else {
      console.log(string1[i] + " " + counter);
      counter = 0;
    }
  }
}
count("thequickbrownfoxjumpsoverthelazydog");
Phiter
  • 14,570
  • 14
  • 50
  • 84
f0rta
  • 19
  • 3
  • 7
  • 1
    `(string1[i] === string1[i + 1])` should work – TheChetan Feb 28 '18 at 18:03
  • It was very smart splitting and sorting alphabetically. The previous comment points the main mistatke in your code. But about counting letters that appear only once, it'll not work if you use this approach of checking if the next letter is the same. – Phiter Feb 28 '18 at 18:05
  • 2
    Ask yourself: how would I do that in the real life? Picture a very long row of cards, with a letter written on each card. How would you count how many A's are there? How many B's? All at once? – georg Feb 28 '18 at 18:14
  • @georg are u a teacher in real life? :-) – Ele Feb 28 '18 at 18:16
  • 1
    @Ele: sometimes ;) – georg Feb 28 '18 at 18:19
  • @TheChetan yes, it does. Thanks a lot! – f0rta Feb 28 '18 at 18:22
  • @Phiter Haha, thanks :) it will if I initialize with counter = 1. I don't know how I missed this, seeing all the letters being displayed made me think my program displays all the letters and counts how many times it appears. If the letter isn't there, it just won't appear in the log. I didn't pay enough attention to this :( – f0rta Feb 28 '18 at 18:23
  • Does this answer your question? [Count the number of occurrences of a character in a string in Javascript](https://stackoverflow.com/questions/881085/count-the-number-of-occurrences-of-a-character-in-a-string-in-javascript) – Nick Apr 02 '20 at 12:12

6 Answers6

2

Use the function reduce to avoid the problem with only one occurence.

function count(string) {
  return string.split("").reduce((a, letter) => {
    a[letter] = (a[letter] || 0) + 1;
    return a;
  }, {});
}
console.log(count("thequickbrownfoxjumpsoverthelazydog"));
.as-console-wrapper { max-height: 100% !important; top: 0; }

Snippet with explanation

function count(string) {
  return string.split("").reduce((a, letter) => {
    var currentCount = a[letter];
    if (currentCount) { 
      currentCount = currentCount + 1; // If previously counted + 1
    } else {
      currentCount = 1; // Else initialize with first occurence.
    }
    
    a[letter] = currentCount; //Store the new count.
    
    return a;
  }, {});
}

console.log(count("thequickbrownfoxjumpsoverthelazydog"));

Resource

Ele
  • 33,468
  • 7
  • 37
  • 75
  • This is a very elegant approach but I think it'd better if you could break it down explaining the steps. If OP is a beginner, he won't understand a thing. – Phiter Feb 28 '18 at 18:07
  • Great answer. I will try your method too. Thanks a lot! – f0rta Feb 28 '18 at 18:25
2

Two minor errors in your code.

  • Matching condition should be string1[i] == string1[i + 1]
  • Initiate counters with value 1 as each value will occur atleast one time.

function count(string) {
  let string1 = string.split("").sort().join("");
  let counter = 1;
  for (let i = 0; i < string.length; i++) {
    if (string1[i] == string1[i + 1]) {
      counter++;
    } else {
      console.log(string1[i] + " " + counter);
      counter = 1;
    }
  }
}
count("thequickbrownfoxjumpsoverthelazydog");

I would suggest you to use a different approach which will use .reduce and will return a nice object of the counts.

function count(string) {
  return string.split("").reduce(
    (acc, el) => {
      if(acc.hasOwnProperty(el))
        acc[el]++;
      else
        acc[el] = 1;
      return acc;
    }, {}
  )
}
var data = count("thequickbrownfoxjumpsoverthelazydog");
console.log(data);
void
  • 36,090
  • 8
  • 62
  • 107
  • Yeah, doing what you've said fixed it. I will try the .reduce approach too. Thanks a lot. – f0rta Feb 28 '18 at 18:25
1

Another approach I haven't seen here:

const count = (str) => {
  let freq = {};
  for(let i = 0; i < str.length; i++) { // you can use for...of instead!
    const currentLetter = str.charAt(i);
    freq[currentLetter] = freq[currentLetter] + 1 || 1;
  }
  return freq;
}
console.log(count("thequickbrownfoxjumpsoverthelazydog"));
  1. Create empty object
  2. Assign a letter as a key and add + 1 to value OR set value to 1 if key doesn't exist.
  3. Return the object.
Tomasz Bubała
  • 2,093
  • 1
  • 11
  • 18
  • `for(let i = 0; i < str.length; i++) { currentLetter = str.charAt(i);` - JS can do better than that. – georg Feb 28 '18 at 18:18
  • both... This is how we used to write JS 10 years ago, but the language has changed significantly since then. – georg Feb 28 '18 at 18:21
  • I used `for` since OP is clearly familiar with it. You suggest using bracket notation over `charAt` or am i missing something? – Tomasz Bubała Feb 28 '18 at 18:23
  • yep, `for (let currentLetter of str)` would look better IMO. – georg Feb 28 '18 at 18:24
  • Thanks for your alternative. I will try it. – f0rta Feb 28 '18 at 18:26
  • @georg, you're definitely right about `for...of` - isn't `charAt` slightly better supported than bracket notation though? Thanks a lot for your insight anyway! :) – Tomasz Bubała Feb 28 '18 at 18:27
  • 1
    @TomaszBubała: actually, `.charAt` (and `.split('')` as used by other posters) are quite dangerous. Be prepared for nasty surprises when using them with high-order unicodes, see https://stackoverflow.com/a/48989438/989121. `for..of` (or `[...str].map`) are preferred methods to iterate strings nowadays. – georg Feb 28 '18 at 18:31
  • Duly noted! Thanks a lot. – Tomasz Bubała Feb 28 '18 at 18:35
0

You can do it like this

function count(text){
  var i = 0;
  var j = 0;
  var chars = new Array();
  var occurs = new Array();

  for(i = 0;i < text.length;i++){
    //save current char
    chars.push(text[i]);

    //get occurences
    occurs.push(countOccurs(text, text[i]));
  }

  //clean for duplicates
  for(i = 0;i < chars.length;i++){
    for(j = (i + 1);j < chars.length;j++){
      if(chars[i] == chars[j]){
        chars[j] = "";
        occurs[j] = 0;
      }
    }
  }

  //print it!
  for(i = 0;i < chars.length;i++){
    if(chars[i] != '')
      console.log("The char " + chars[i] + " appears " + occurs[i] + " times.");
  }
}

function countOccurs(text, character){
  var i = 0;
  var ret = 0;

  for(i = 0;i < text.length;i++)
    if(text[i] == character)
      ret++

  return ret;
}

count("abcdefabcd");

So you just count each char's occurs then clean the arrays.

David
  • 21
  • 1
  • 7
0
const counterFunc = (string) => {
    let  counter = {};
    string.split('').map((char) => {
        if(typeof counter[char] !== 'undefined') {
            counter = {
                ...counter,
                [char]: counter[char] + 1
            }
        } else {
            counter[char] = 1
        }
    })

    return Object.keys(counter).map( k => {
        return  k + counter[k];
    }).join('');
};

console.log(counterFunc("abcabcabcabcadftyeacrtfvcserfvaserdcvfrt"))
Aathi
  • 2,599
  • 2
  • 19
  • 16
0

Hello People This is my first post in stack Over flow.

This is the Shortest Code that i can suggest.

function letterOccurence(string)
{
    let countedString ={};

    for(let letter of string)

    {
           countedString[letter] = (countedString[letter] || 0)+1; //This will count the occurrence of each letter 
    }
    return countedString;
}
console.log(letterOccurence(("thequickbrownfoxjumpsoverthelazydog")));
vimuth
  • 5,064
  • 33
  • 79
  • 116