snippetjavascriptTip
How can I group and count values in a JavaScript array?
Viewed 0 times
javascriptgroupandhowcountcanarrayvalues
Problem
Finding the count of each value in an array can come in handy in a lot of situations. It's also fairly straightforward to implement, both for primitive and complex values, using JavaScript's
You can use
You can also group the elements of an array based on a given function and return the count of elements in each group. This can be useful when you want to group elements based on a specific property or a function.
To do so, you can use
Both of the previous examples use objects to store the frequencies of the values. However, you can also use a
Array methods.You can use
Array.prototype.reduce() to create an object with the unique values of an array as keys and their frequencies as the values. Use the nullish coalescing operator (??) to initialize the value of each key to 0 if it doesn't exist and increment it by 1 every time the same value is encountered.You can also group the elements of an array based on a given function and return the count of elements in each group. This can be useful when you want to group elements based on a specific property or a function.
To do so, you can use
Array.prototype.map() to map the values of an array to a function or property name, and then use Array.prototype.reduce() to create an object, where the keys are produced from the mapped results.Both of the previous examples use objects to store the frequencies of the values. However, you can also use a
Map to store the frequencies. This can be useful if you need to keep the insertion order of the keys or if you need to iterate over the keys in the order they were inserted. It's also more efficient when you need to delete keys or check for the existence of a key.Solution
const frequencies = arr =>
arr.reduce((a, v) => {
a[v] = (a[v] ?? 0) + 1;
return a;
}, {});
frequencies(['a', 'b', 'a', 'c', 'a', 'a', 'b']);
// { a: 4, b: 2, c: 1 }
frequencies([...'ball']);
// { b: 1, a: 1, l: 2 }You can also group the elements of an array based on a given function and return the count of elements in each group. This can be useful when you want to group elements based on a specific property or a function.
To do so, you can use
Array.prototype.map() to map the values of an array to a function or property name, and then use Array.prototype.reduce() to create an object, where the keys are produced from the mapped results.Both of the previous examples use objects to store the frequencies of the values. However, you can also use a
Map to store the frequencies. This can be useful if you need to keep the insertion order of the keys or if you need to iterate over the keys in the order they were inserted. It's also more efficient when you need to delete keys or check for the existence of a key.When dealing with data that changes often, you may need to recalculate frequencies as needed. This can become tedious and inefficient, especially if you only need to keep track of the frequencies and have no need for the original array.
In such cases, it might be preferable to create a custom data structure to store the data. This data structure will be able to keep track of the frequencies of the values it contains and update them as needed.
Moreover, you may want to be able to check the frequency of any value, even if it doesn't exist in the data structure. This also comes in handy if you want to easily increment or decrement the frequency of a value. Let's take a look at how you can implement such a data structure:
Code Snippets
const frequencies = arr =>
arr.reduce((a, v) => {
a[v] = (a[v] ?? 0) + 1;
return a;
}, {});
frequencies(['a', 'b', 'a', 'c', 'a', 'a', 'b']);
// { a: 4, b: 2, c: 1 }
frequencies([...'ball']);
// { b: 1, a: 1, l: 2 }const countBy = (arr, fn) =>
arr
.map(typeof fn === 'function' ? fn : val => val[fn])
.reduce((acc, val) => {
acc[val] = (acc[val] || 0) + 1;
return acc;
}, {});
countBy([6.1, 4.2, 6.3], Math.floor);
// {4: 1, 6: 2}
countBy(['one', 'two', 'three'], 'length');
// {3: 2, 5: 1}
countBy([{ count: 5 }, { count: 10 }, { count: 5 }], x => x.count);
// {5: 2, 10: 1}const frequenciesMap = arr =>
arr.reduce((a, v) => a.set(v, (a.get(v) ?? 0) + 1), new Map());
frequenciesMap(['a', 'b', 'a', 'c', 'a', 'a', 'b']);
// Map(3) { 'a' => 4, 'b' => 2, 'c' => 1 }
const countByMap = (arr, fn) =>
arr
.map(typeof fn === 'function' ? fn : val => val[fn])
.reduce((acc, val) => {
acc.set(val, (acc.get(val) || 0) + 1);
return acc;
}, new Map());
countByMap([6.1, 4.2, 6.3], Math.floor);
// Map(2) { 6 => 2, 4 => 1 }
countByMap(['one', 'two', 'three'], 'length');
// Map(2) { 3 => 2, 5 => 1 }
countByMap([{ count: 5 }, { count: 10 }, { count: 5 }], x => x.count);
// Map(2) { 5 => 2, 10 => 1 }Context
From 30-seconds-of-code: count-grouped-elements
Revisions (0)
No revisions yet.