Evan
Evan

Reputation: 2497

Javascript get all the most frequent characters in a string

I need help on how can I get not just one but other most common character/letter in a string.

my code only works on getting one of the common character.

but when more than one character are equally common only one are returned. I would like it to return two character if two character are common.

const x = mostCommonCharacter("abbbcddefffg");
console.log(x); // result is *b* 

if b and f are most common I would like to return bf

  function mostCommonCharacter(str) {
  const charHolder = {}; // { a: 1, b: 3, c: 1, d: 2, e: 1, f: 3, g: 1 }

  str
    .toLowerCase()
    .split("")
    .forEach(char => {
      if (char != " ") {
        if (charHolder[char] == null) {
          charHolder[char] = 1;
        } else {
          charHolder[char] += 1;
        }
      }
    });
  let highest_num = 0;
  let letter = "";
  for (const key in charHolder) {
    if (charHolder[key] > highest_num) {
      highest_num = charHolder[key];
      letter = key;
    }
  }
  return letter;
}

but It only return one most common character which is "b"

what I need is for it to return "b" and "f" because both of them are most common. and not just b is there a way to do this?

Upvotes: 2

Views: 2363

Answers (4)

Rohit Kashyap
Rohit Kashyap

Reputation: 1592

A solution involving an algorithmic approach using hashmaps.

var a = 'abbbcddefffg';

const counter = (str) => {
  var ch = {};
  for(var i=0; i<str.length;i++) {
    
    if(str[i] in ch) {
      ch[str[i]] += 1
    } else {
      ch[str[i]] = 1
    }
  }
  return ch;
}

let sorted = (list) => Object.fromEntries(Object.entries(list).sort( (a,b) => b[1] - a[1] )) 

let counterInSorted = sorted(counter(a));

let getXMostOccuring = (stringObj, x) => {
  return Object.keys(stringObj).slice(0,x).join('');
}


console.log('First x elements occuring frequently');
console.log(getXMostOccuring(counterInSorted,2));

console.log(sorted(counter(a)))

This approach will provide with the frequency of each character in a sorted manner. You can now decide to get 'x' most occurring characters.

Upvotes: 0

Amardeep Bhowmick
Amardeep Bhowmick

Reputation: 16908

Please find a more compact approach where you can use Array.prototype.reduce to get the {letter: frequency} map in an object from the string after splitting it into an array.

Then use the Object.entries to get the most frequent and second frequent letters after sorting the entries of [key, values]:

const x = mostCommonCharacter("abbbcddefffg");
function mostCommonCharacter(str){
  const dict = str.split("").reduce((acc, ele) =>{
    acc[ele] = (acc[ele] || 0) + 1;
    return acc;
  }, {});
  const letters = Object.entries(dict).sort((a, b) => b[1] - a[1]).map(a => a[0]);
  return letters.length > 1 ? letters.slice(0, 2).join("") : letters.length > 0 ? letters[0] : null;
}
console.log(x);

Upvotes: 0

thejohnbackes
thejohnbackes

Reputation: 1255

You could accomplish this with a simple change. Just add the letter to "letters" if it is equal to "highest_num".

  let highest_num = 0;
  let letters = "";
  for (const key in charHolder) {
    if (charHolder[key] > highest_num) {
      highest_num = charHolder[key];
      letters = key;
    } else if (charHolder[key] === highest_num) {
      letters += key;
    }
  }

Upvotes: 1

Maheer Ali
Maheer Ali

Reputation: 36574

Get the highest_num and then again iterate through object and get those letters for which count is equal to highest_num

function mostCommonCharacter(str) {
  const charHolder = {}; // { a: 1, b: 3, c: 1, d: 2, e: 1, f: 3, g: 1 }

  str
    .toLowerCase()
    .split("")
    .forEach(char => {
      if (char != " ") {
        if (charHolder[char] == null) {
          charHolder[char] = 1;
        } else {
          charHolder[char] += 1;
        }
      }
    });
  let highest_num = 0;
  for (const key in charHolder) {
    if (charHolder[key] > highest_num) {
      highest_num = charHolder[key];
    }
  }
  let res = '';
  for(let k in charHolder){
    if(charHolder[k] === highest_num){
      res += k;
    }
  }
  return res;
}

console.log(mostCommonCharacter("abbbcddefffg"))

A shorter version of the code can be obtained by using reduce() and Math.max

function mostCommonCharacter(str) {
  const charHolder = str
                      .toLowerCase()
                      .split('')
                      .reduce((ac,a) => (ac[a] = ac[a] + 1 || 1, ac), {});

  let max = Math.max(...Object.values(charHolder));

  return Object.entries(charHolder).reduce((ac,[k,v]) =>v === max ? ac + k : ac, '');
  
}

console.log(mostCommonCharacter("abbbcddefffg"))

Upvotes: 1

Related Questions