Blythe Simmons
Blythe Simmons

Reputation: 253

Javascript: Counting frequency of emojis in text

I'm trying to count the frequency of emojis in a block of text. For example:

"I love 🚀🚀🚀 so much 😍 " -> [{🚀:3}, {😍:1}]

In order to count the frequency of characters in a block of text, I'm using

function getFrequency(string) {
    var freq = {};
    for (var i=0; i<string.length;i++) {
        var character = string.charAt(i);
        if (freq[character]) {
           freq[character]++;
        } else {
           freq[character] = 1;
        }
    }

    return freq;
};

source: https://stackoverflow.com/a/18619975/4975358

^The above code works great, but it does not recognize emoji characters:

{�: 1,  �: 3,  �: 2}

Also, I'd prefer the output to be a list of json objects of length 1, as opposed to one long json object.

Upvotes: 5

Views: 1760

Answers (2)

le_m
le_m

Reputation: 20238

You can use the callback of the String.replace function and a unicode aware RegExp detecting everything from the unicode blocks "Miscellaneous Symbols" to "Pictographs Transport and Map Symbols" (0x1F300 to 0x1F6FF):

let str = "I love 🚀🚀🚀 so much 😍 ";

let freq = {};
str.replace(/[\u{1F300}-\u{1F6FF}]/gu, char => freq[char] = (freq[char] || 0) + 1);

console.log(freq);

If you prefer to avoid RegExp or String.replace, you can destructure the string into an array and reduce it to the frequencies as follows:

let str = "I love 🚀🚀🚀 so much 😍 ";

let freq = [...str].reduce((freq, char) => {
  if (char >= '\u{1F300}' && char < '\u{1F700}') freq[char] = (freq[char] || 0) + 1;
  return freq;
}, {});

console.log(freq);

Upvotes: 7

user663031
user663031

Reputation:

charAt won't help you here. for...of will parse the string correctly into Unicode codepoints including those in the astral plane. We use character.length to determine whether or not this is a supplementary plane character. If you really want to know if it's an emoji, you'd need to tighten this up.

const input = "I love 🚀🚀🚀 so much 😍 ";
    
function getFrequency(string) {
  var freq = {};
  for (character of string) {
    if (character.length === 1) continue;
    if (freq[character]) {
      freq[character]++;
    } else {
      freq[character] = 1;
    }
  }
  return freq;
 };
 
 console.log(getFrequency(input));

To create an array of single-valued objects, run the output through this:

function breakProperties(obj) {
  return Object.keys(obj).map(function(key) {
    var result = {};
    result[key] = obj[key];
    return result;
  });
}

Upvotes: 6

Related Questions