DEV Community

Kenny
Kenny

Posted on

Character Frequency

Hi everyone Today, we're going to go over the Character Frequency Toy Problem!
This toy problem's input will be string and output an array of arrays that is sorted in descending order by frequency and then by ascending order by character for example:

characterFrequency('mississippi');
// =>
// [
//   ['i', 4],
//   ['s', 4],
//   ['p', 2],
//   ['m', 1],
// ]

To begin we know our

  • Input: String

  • Output: An array of arrays Where the subarrays' first element is the character and second is a number of how many times it had appeared in the provided string.
  • So lets break down the problem a little bit We know our output should be an array of arrays, so lets create an array variable, followed by an empty object, that will be our letter counter. When we're iterating through the string to see how many character out string has and next we're going to add them into our object as we're adding them into our string we're going to give each character a number value of how many occurrences the character appears

    Our current output should look like this so far:

    { m: 1, 
      i: 5,
      s: 2, 
      p: 4 }
    
    const characterFrequency = (string) => {
      let result = [];
    // create an object to keep store the value as key value pairs
      let letterCount = {};
     // loop through string
      for (let i = 0; i < string.length; i++) {
        // if the letter only appears once keep its count at one
          //else increment the count
        !letterCount[string[i]] ? letterCount[string[i]] = 1 : letterCount[string[i]]++;    
      }
    

    Next we're going to initialize a new variable grab the keys of our letter count object using Object.Keys now that now new variable is an array we could sort it accordingly

    Afterwards we'll iterate one last time for our inner array
    within our loop we'll create another array variable representing our inner array we're going to add the character in the first index of our inner array and the number in the second index of inner array and push the last part of our inner array into our final result array.

     for (let j = 0; j < arrayMaker.length; j++) {
        let innerArray = [];
        // letters added to innerArray
        innerArray[0] = arrayMaker[j];
        // numbers added to innerArray
        innerArray[1] = letterCount[arrayMaker[j]];
        result.push(innerArray);
      }
    

    Our final solution should look at little something like this:

    const characterFrequency = (string) => {
      let result = [];
      // create an object to keep store the value as key value pairs
      let letterCount = {};
      // loop through string
      for (let i = 0; i < string.length; i++) {
        // if the letter only appears once keep its count at one
        if (!letterCount[string[i]]) {
          letterCount[string[i]] = 1;
        } else {
          //else increment the count
          letterCount[string[i]]++;
        }
      }
      // turn the object into an array
      let arrayMaker = Object.keys(letterCount);
      // console.log(arrayMaker);
      // sort the array
      arrayMaker.sort(function(a, b) {
        if (letterCount[b] === letterCount[a]) {
          if (a > b) {
            return 1;
          } else if (a < b) {
            return -1;
          } else {
            return 0;
          }
        }
        return letterCount[b] - letterCount[a];
      });
      // loop through the sorted array
      for (let j = 0; j < arrayMaker.length; j++) {
        let innerArray = [];
        // letters added to innerArray
        innerArray[0] = arrayMaker[j];
        // numbers added to innerArray
        innerArray[1] = letterCount[arrayMaker[j]];
        result.push(innerArray);
      }
      // console.log(result);
      return result;
    
    };
    

    Thank you for taking the time looking over this blog post! This problem was fun to solve out. I hope it helps those who had troubles with this problem!
    Til next time Thank you!

    Top comments (1)

    Collapse
     
    jpantunes profile image
    JP Antunes

    Once you are comfortable with Array.reduce and arrow syntax, you can try this:

    const freqMap = str => [...str].reduce( (acc, val) => {acc[val] = acc[val] + 1 || 1; return acc}, new Map());