const result = [...str].reduce((acc, n) => (acc[n] = (acc[n] ?? 0) + 1, acc), {});
Или, в более общем виде:
function count(data, key = n => n) {
const counted = {};
for (const n of data) {
const k = key(n);
counted[k] = -~counted[k];
}
return counted;
}
const result = count(str);
Работать можно не только со строками, но и, например, с массивами:
const nums = [ -Infinity, -1, 0, 0, 0, 0, 69, 187, 666 ];
console.log(count(nums, Math.sign)); // {0: 4, 1: 3, -1: 2}
Или коллекциями DOM-элементов:
<div data-country="USA">New York</div>
<div data-country="USA">Boston</div>
<div data-country="USA">Las Vegas</div>
<div data-country="Japan">Osaka</div>
<div data-country="Japan">Tokyo</div>
<div data-country="Japan">Kyoto</div>
<div data-country="Japan">Yokohama</div>
<div data-country="Germany">Munich</div>
<div data-country="Germany">Dresden</div>
const cities = document.querySelectorAll('[data-country]');
console.log(count(cities, n => n.dataset.country)); // {USA: 3, Japan: 4, Germany: 2}
Вообще, с любыми итерируемыми объектами работать можно:
count(Array(9).keys(), n => [ 'чётные', 'нечётные' ][n & 1]) // {чётные: 5, нечётные: 4}