# Counting the frequency of certain entries in a list of JSON objects

I have a list of JSON objects that looks like this:

[{
url: '/home',
...
}, {
url: '/analytics',
...
}]


I'm using the following function to count the frequencies of the URLs in order to pass it to a c3.js chart.

var getSectionFrequencyData = function(data) {
var frequencies = {};
data.map(function(entry) {
var matches = /[a-z]+/g.exec(entry.url);
var url = 'home';
if (matches) {
url = matches[0];
}
frequencies[url] = frequencies[url] ? frequencies[url] + 1 : 1;
});
var items = Object.keys(frequencies).map(function(section) {
return [section, frequencies[section]];
}).sort(function(a, b) {
return b[1] - a[1];
}).slice(0, 10);
return [
['sections'].concat(items.map(item => item[0])),
['frequency'].concat(items.map(item => item[1]))
];
};


This code works, but the frequency counting, sorting, and grouping seems extremely overengineered and clunky. Best practices for this?

• use more of ES2015+ if you use some parts of it anyway - for example Map is handy here;
• don't mix function and => notations - unless the former is absolutely required;
• don't use array .map if you don't need the output array - to avoid garbage collection lags;
const getSectionFrequencyData = data => {
const getSection = entry => /[a-z]+|$/.exec(entry.url || '')[0]; const frequencies = new Map(); for (const entry of data) { const section = getSection(entry) || 'home'; frequencies.set(section, (frequencies.get(section) || 0) + 1); } const sorted10 = new Map( [...frequencies.entries()] .sort((a, b) => b[1] - a[1]) .slice(0, 10) ); return [ ['sections', ...sorted10.keys()], ['frequency', ...sorted10.values()], ]; };  • Thanks for the answer. I'm super intrigued though, because it contains so many things that I haven't seen before or consider as evil hacks. Using Map seems very elegant for the last part. I'll accept your answer for now and leave further questions about this magic later. – omgimanerd Jul 7 '17 at 20:15 • The only hack I've used is [a-z]+|$ to make exec produce at least an empty string (I thought it's quite an obvious regex). What else? || 0 is a norm, ... is a ES2015 spread syntax. – wOxxOm Jul 7 '17 at 20:23
• I didn't know about that regex trick and I didn't know about the existence of Map. I knew about spread syntax and || 0. I prefer to avoid || 0 because it can behave differently when not using numbers. Using spread syntax to create a copy seemed interesting and hackish. After reading the MDN docs though, it seems like that's an intended use case for it. ¯_(ツ)_/¯ – omgimanerd Jul 7 '17 at 20:30
• || 0 is okay in a fully controlled case. Otherwise even integerVar++ in a for loop may be called a hack. – wOxxOm Jul 7 '17 at 20:35