Как насчет опции ECMAScript2015.
const a = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];
const aCount = new Map([...new Set(a)].map(
x => [x, a.filter(y => y === x).length]
));
aCount.get(5) // 3
aCount.get(2) // 5
aCount.get(9) // 1
aCount.get(4) // 1
В этом примере массив входных данных передается конструктору Set
, создавая коллекцию уникальных ценности.Синтаксис затем расширяет эти значения в новый массив, так что мы можем вызвать map
и преобразовать его в двумерный массив из [value, count]
пар, то есть следующую структуру:
Array [
[5, 3],
[2, 5],
[9, 1],
[4, 1]
]
Новый массив затем передается конструктору Map
, в результате чего получается повторяемый объект:
Map {
5 => 3,
2 => 5,
9 => 1,
4 => 1
}
Отличная вещь о Map
Объект в том, что он сохраняет типы данных - то есть aCount.get(5)
вернет 3
, но aCount.get("5")
вернет undefined
.Он также позволяет любому значению / типу выступать в качестве ключа, что означает, что это решение также будет работать с массивом объектов.
function frequencies(/* {Array} */ a){
return new Map([...new Set(a)].map(
x => [x, a.filter(y => y === x).length]
));
}
let foo = { value: 'foo' },
bar = { value: 'bar' },
baz = { value: 'baz' };
let aNumbers = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4],
aObjects = [foo, bar, foo, foo, baz, bar];
frequencies(aNumbers).forEach((val, key) => console.log(key + ': ' + val));
frequencies(aObjects).forEach((val, key) => console.log(key.value + ': ' + val));