Reputation: 253
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
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
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