计数数组元素的出现/频率

在Javascript中,我试图采取数字值的初始数组,并计算其中的元素。理想情况下,结果将是两个新数组,第一个数组指定每个唯一元素,第二个数组包含每个元素出现的次数。但是,我愿意听取关于输出格式的建议。

例如,如果初始数组是:

5, 5, 5, 2, 2, 2, 2, 2, 9, 4

然后将创建两个新数组。第一个将包含每个唯一元素的名称:

5, 2, 9, 4

第二个将包含该元素在初始数组中出现的次数:

3, 5, 1, 1

因为数字5在初始数组中出现了三次,数字2出现了五次,9和4都出现了一次。

我一直在寻找解决方案,但似乎没有一个可行,而且我自己尝试过的每件事最后都出奇地复杂。任何帮助都将不胜感激!

谢谢:)

703513 次浏览

你可以使用一个对象来保存结果:

const arr = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];
const counts = {};


for (const num of arr) {
counts[num] = counts[num] ? counts[num] + 1 : 1;
}


console.log(counts);
console.log(counts[5], counts[2], counts[9], counts[4]);

所以,现在你的counts对象可以告诉你一个特定数字的计数是多少:

console.log(counts[5]); // logs '3'

如果你想获得一个成员数组,只需使用keys()函数

keys(counts); // returns ["5", "2", "9", "4"]

不要使用两个数组的结果,使用一个对象:

a      = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];
result = { };
for(var i = 0; i < a.length; ++i) {
if(!result[a[i]])
result[a[i]] = 0;
++result[a[i]];
}

那么result将看起来像:

{
2: 5,
4: 1,
5: 3,
9: 1
}

const arr = [2, 2, 5, 2, 2, 2, 4, 5, 5, 9];


function foo (array) {
let a = [],
b = [],
arr = [...array], // clone array so we don't change the original when using .sort()
prev;


arr.sort();
for (let element of arr) {
if (element !== prev) {
a.push(element);
b.push(1);
}
else ++b[b.length - 1];
prev = element;
}


return [a, b];
}


const result = foo(arr);
console.log('[' + result[0] + ']','[' + result[1] + ']')
console.log(arr)

查看下面的代码。

<html>
<head>
<script>
// array with values
var ar = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];


var Unique = []; // we'll store a list of unique values in here
var Counts = []; // we'll store the number of occurances in here


for(var i in ar)
{
var Index = ar[i];
Unique[Index] = ar[i];
if(typeof(Counts[Index])=='undefined')
Counts[Index]=1;
else
Counts[Index]++;
}


// remove empty items
Unique = Unique.filter(function(){ return true});
Counts = Counts.filter(function(){ return true});


alert(ar.join(','));
alert(Unique.join(','));
alert(Counts.join(','));


var a=[];


for(var i=0; i<Unique.length; i++)
{
a.push(Unique[i] + ':' + Counts[i] + 'x');
}
alert(a.join(', '));


</script>
</head>
<body>


</body>
</html>

编辑2020:这是一个相当老的答案(9年)。扩展本机prototype总是会生成讨论。虽然我认为程序员可以自由选择自己的编程风格,但这里有一个(更现代的)方法来解决问题,而不扩展Array.prototype:

{
// create array with some pseudo random values (1 - 5)
const arr = Array.from({length: 100})
.map( () => Math.floor(1 + Math.random() * 5) );
// frequencies using a reducer
const arrFrequencies = arr.reduce((acc, value) =>
({ ...acc, [value]: acc[value] + 1 || 1}), {} )
console.log(arrFrequencies);
console.log(`Value 4 occurs ${arrFrequencies[4]} times in arrFrequencies`);


// bonus: restore Array from frequencies
const arrRestored = Object.entries(arrFrequencies)
.reduce( (acc, [key, value]) => acc.concat(Array(value).fill(+key)), [] );
console.log(arrRestored.join());
}
.as-console-wrapper { top: 0; max-height: 100% !important; }

The old (2011) answer: you could extend Array.prototype, like this:

{
Array.prototype.frequencies = function() {
var l = this.length,
result = {
all: []
};
while (l--) {
result[this[l]] = result[this[l]] ? ++result[this[l]] : 1;
}
// all pairs (label, frequencies) to an array of arrays(2)
for (var l in result) {
if (result.hasOwnProperty(l) && l !== 'all') {
result.all.push([l, result[l]]);
}
}
return result;
};


var freqs = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4].frequencies();
console.log(`freqs[2]: ${freqs[2]}`); //=> 5
  

// or
var freqs = '1,1,2,one,one,2,2,22,three,four,five,three,three,five'
.split(',')
.frequencies();
    

console.log(`freqs.three: ${freqs.three}`); //=> 3
  

// Alternatively you can utilize Array.map:


Array.prototype.frequencies = function() {
var freqs = {
sum: 0
};
this.map(function(a) {
if (!(a in this)) {
this[a] = 1;
} else {
this[a] += 1;
}
this.sum += 1;
return a;
}, freqs);
return freqs;
}
}
.as-console-wrapper { top: 0; max-height: 100% !important; }

const occurrences = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4].reduce(function (acc, curr) {
return acc[curr] ? ++acc[curr] : acc[curr] = 1, acc
}, {});


console.log(occurrences) // => {2: 5, 4: 1, 5: 3, 9: 1}

试试这个:

Array.prototype.getItemCount = function(item) {
var counts = {};
for(var i = 0; i< this.length; i++) {
var num = this[i];
counts[num] = counts[num] ? counts[num]+1 : 1;
}
return counts[item] || 0;
}

你可以通过使用count函数扩展数组来简化这一点。它的工作原理类似于Ruby的Array#count,如果你熟悉它的话。

Array.prototype.count = function(obj){
var count = this.length;
if(typeof(obj) !== "undefined"){
var array = this.slice(0), count = 0; // clone array and reset count
for(i = 0; i < array.length; i++){
if(array[i] == obj){ count++ }
}
}
return count;
}

用法:

let array = ['a', 'b', 'd', 'a', 'c'];
array.count('a'); // => 2
array.count('b'); // => 1
array.count('e'); // => 0
array.count(); // => 5

Gist


编辑

然后,您可以使用Array#filter获取第一个数组,其中包含每个出现的项:

let occurred = [];
array.filter(function(item) {
if (!occurred.includes(item)) {
occurred.push(item);
return true;
}
}); // => ["a", "b", "d", "c"]

第二个数组,包含出现的次数,使用Array#countArray#map:

occurred.map(array.count.bind(array)); // => [2, 1, 1, 1]

或者,如果顺序无关紧要,你可以直接返回一个键值对:

let occurrences = {}
occurred.forEach(function(item) { occurrences[item] = array.count(item) });
occurences; // => {2: 5, 4: 1, 5: 3, 9: 1}

这里有一些对眼睛来说简单的东西……

function count(a,i){
var result = 0;
for(var o in a)
if(a[o] == i)
result++;
return result;
}

既然你想要所有的事件…

function count(a){
var result = {};
for(var i in a){
if(result[a[i]] == undefined) result[a[i]] = 0;
result[a[i]]++;
}
return result;
}

如果你使用下划线,你可以走功能路线

a = ['foo', 'foo', 'bar'];


var results = _.reduce(a,function(counts,key){ counts[key]++; return counts },
_.object( _.map( _.uniq(a), function(key) { return [key, 0] })))

第一个数组是

_.keys(results)

第二个数组是

_.values(results)

如果本地javascript函数可用,其中大部分将默认为本地javascript函数

演示:http://jsfiddle.net/dAaUU/

我认为这是最简单的方法如何计数发生在数组中相同的值。

var a = [true, false, false, false];
a.filter(function(value){
return value === false;
}).length

如果使用下划线或lodash,这是最简单的事情:

_.countBy(array);

这样:

_.countBy([5, 5, 5, 2, 2, 2, 2, 2, 9, 4])
=> Object {2: 5, 4: 1, 5: 3, 9: 1}

正如其他人指出的那样,然后可以对结果执行_.keys()_.values()函数,以分别获得唯一的数字及其出现次数。但根据我的经验,原始对象更容易处理。

如果你喜欢单线。

arr.reduce(function(countMap, word) {countMap[word] = ++countMap[word] || 1;return countMap}, {});

< p > 编辑(6/12/2015): 由内而外的解释。 countMap是一个映射一个单词的频率的映射,我们可以看到匿名函数。reduce所做的是应用带有参数的函数作为所有数组元素,并将countMap作为最后一次函数调用的返回值传递。最后一个参数({})是第一次函数调用时countMap的默认值

我在codewars上解决了一个类似的问题,并设计了以下解决方案。

这将给出数组中整数的最高计数以及整数本身。我认为它也可以应用于字符串数组。

要正确地对字符串排序,请从sort()部分中删除function(a, b){return a-b}

function mostFrequentItemCount(collection) {
collection.sort(function(a, b){return a-b});
var i=0;
var ans=[];
var int_ans=[];
while(i<collection.length)
{
if(collection[i]===collection[i+1])
{
int_ans.push(collection[i]);
}
else
{
int_ans.push(collection[i]);
ans.push(int_ans);
int_ans=[];
}
i++;
}


var high_count=0;
var high_ans;


i=0;
while(i<ans.length)
{
if(ans[i].length>high_count)
{
high_count=ans[i].length;
high_ans=ans[i][0];
}
i++;
}
return high_ans;
}

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));

这是一个经典的计算数组的方法。

var arr = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];
var counted = [], count = [];
var i = 0, j = 0, k = 0;
while (k < arr.length) {
if (counted.indexOf(arr[k]) < 0) {
counted[i] = arr[k];
count[i] = 0;
for (j = 0; j < arr.length; j++) {
if (counted[i] == arr[j]) {
count[i]++;
}
}
i++;
} else {
k++;
}
}

如果您希望得到字母顺序的结果,可以先对其排序,但如果您希望保留输入数据的顺序,则可以尝试这种方法。嵌套循环可能比本页上的其他一些方法要慢一些。

基于@adamse@pmandell回答(我赞成),在ES6中,你可以在一行中这样做:

  • 2017年的编辑:我使用||来减少代码大小,使其更具可读性。

var a=[7,1,7,2,2,7,3,3,3,7,,7,7,7];
alert(JSON.stringify(


a.reduce((r,k)=>{r[k]=1+r[k]||1;return r},{})


));


它可以用于数字符:

var s="ABRACADABRA";
alert(JSON.stringify(


s.split('').reduce((a, c)=>{a[c]++?0:a[c]=1;return a},{})


));

const data = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4]


function count(arr) {
return arr.reduce((prev, curr) => (prev[curr] = ++prev[curr] || 1, prev), {})
}


console.log(count(data))

有一个更好更简单的方法,我们可以使用ramda.js来做到这一点。 代码示例 < / p > < p > <代码> const必要=[5,5、5、2、2、2、2、2、9日4]; R.countBy (r =比;r)(必要) countBy文档位于文档

var array = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];


function countDuplicates(obj, num){
obj[num] = (++obj[num] || 1);
return obj;
}


var answer = array.reduce(countDuplicates, {});
// answer => {2:5, 4:1, 5:3, 9:1};

如果你仍然需要两个数组,那么你可以像这样使用回答

var uniqueNums = Object.keys(answer);
// uniqueNums => ["2", "4", "5", "9"];


var countOfNums = Object.keys(answer).map(key => answer[key]);
// countOfNums => [5, 1, 3, 1];

或者如果你想让unique enum是数字

var uniqueNums = Object.keys(answer).map(key => +key);
// uniqueNums => [2, 4, 5, 9];

下面是一种计算对象数组中出现次数的方法。它还将第一个数组的内容放在一个新数组中,以便对值进行排序,这样原始数组中的顺序就不会被打乱。然后使用递归函数遍历每个元素并计算数组中每个对象的quantity属性。

var big_array = [
{ name: "Pineapples", quantity: 3 },
{ name: "Pineapples", quantity: 1 },
{ name: "Bananas", quantity: 1 },
{ name: "Limes", quantity: 1 },
{ name: "Bananas", quantity: 1 },
{ name: "Pineapples", quantity: 2 },
{ name: "Pineapples", quantity: 1 },
{ name: "Bananas", quantity: 1 },
{ name: "Bananas", quantity: 1 },
{ name: "Bananas", quantity: 5 },
{ name: "Coconuts", quantity: 1 },
{ name: "Lemons", quantity: 2 },
{ name: "Oranges", quantity: 1 },
{ name: "Lemons", quantity: 1 },
{ name: "Limes", quantity: 1 },
{ name: "Grapefruit", quantity: 1 },
{ name: "Coconuts", quantity: 5 },
{ name: "Oranges", quantity: 6 }
];


function countThem() {
var names_array = [];
for (var i = 0; i < big_array.length; i++) {
names_array.push( Object.assign({}, big_array[i]) );
}


function outerHolder(item_array) {
if (item_array.length > 0) {
var occurrences = [];
var counter = 0;
var bgarlen = item_array.length;
item_array.sort(function(a, b) { return (a.name > b.name) ? 1 : ((b.name > a.name) ? -1 : 0); });


function recursiveCounter() {
occurrences.push(item_array[0]);
item_array.splice(0, 1);
var last_occurrence_element = occurrences.length - 1;
var last_occurrence_entry = occurrences[last_occurrence_element].name;
var occur_counter = 0;
var quantity_counter = 0;
for (var i = 0; i < occurrences.length; i++) {
if (occurrences[i].name === last_occurrence_entry) {
occur_counter = occur_counter + 1;
if (occur_counter === 1) {
quantity_counter = occurrences[i].quantity;
} else {
quantity_counter = quantity_counter + occurrences[i].quantity;
}
}
}


if (occur_counter > 1) {
var current_match = occurrences.length - 2;
occurrences[current_match].quantity = quantity_counter;
occurrences.splice(last_occurrence_element, 1);
}


counter = counter + 1;


if (counter < bgarlen) {
recursiveCounter();
}
}


recursiveCounter();


return occurrences;
}
}
alert(JSON.stringify(outerHolder(names_array)));
}

ES6版本应该更简单(另一个一行解决方案)

let arr = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];
let acc = arr.reduce((acc, val) => acc.set(val, 1 + (acc.get(val) || 0)), new Map());


console.log(acc);
// output: Map { 5 => 3, 2 => 5, 9 => 1, 4 => 1 }

Map代替普通对象帮助我们区分不同类型的元素,否则所有计数都是基于字符串

function countOcurrences(arr){
return arr.reduce((aggregator, value, index, array) => {
if(!aggregator[value]){
return aggregator = {...aggregator, [value]: 1};
}else{
return aggregator = {...aggregator, [value]:++aggregator[value]};
}
}, {})
}

使用滤镜很简单

在本例中,我们简单地分配count,即通过所寻找的键筛选的数组的长度

let array = [{name: "steve", age: 22}, {name: "bob", age: 30}]


let count = array.filter(obj => obj.name === obj.name).length


console.log(count)

关于JS过滤器的更多信息,这里https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

所以这里是我如何做的一些最新的javascript功能:

首先,将数组缩减为计数的Map:

let countMap = array.reduce(
(map, value) => {map.set(value, (map.get(value) || 0) + 1); return map},
new Map()
)
通过使用Map,起始数组可以包含任何类型的对象,计数将是正确的。如果没有Map,某些类型的对象会给你奇怪的计数。 有关差异的更多信息,请参阅Map文档

如果你所有的值都是符号、数字或字符串,这也可以用在对象上:

let countObject = array.reduce(
(map, value) => { map[value] = (map[value] || 0) + 1; return map },
{}
)

或者使用解构和对象扩展语法,以一种没有突变的函数式方式略显花哨:

let countObject = array.reduce(
(value, {[value]: count = 0, ...rest}) => ({ [value]: count + 1, ...rest }),
{}
)

此时,您可以使用Map或object进行计数(与对象不同,映射是直接可迭代的),或将其转换为两个数组。

对于Map:

countMap.forEach((count, value) => console.log(`value: ${value}, count: ${count}`)


let values = countMap.keys()
let counts = countMap.values()

或者对于对象:

Object
.entries(countObject) // convert to array of [key, valueAtKey] pairs
.forEach(([value, count]) => console.log(`value: ${value}, count: ${count}`)


let values = Object.keys(countObject)
let counts = Object.values(countObject)

我对拉姆达的解决方案:

const testArray = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4]


const counfFrequency = R.compose(
R.map(R.length),
R.groupBy(R.identity),
)


counfFrequency(testArray)

REPL链接

使用MAP,你可以在输出中有两个数组:一个包含出现的&另一个是包含出现的次数。

const dataset = [2,2,4,2,6,4,7,8,5,6,7,10,10,10,15];
let values = [];
let keys = [];


var mapWithOccurences = dataset.reduce((a,c) => {
if(a.has(c)) a.set(c,a.get(c)+1);
else a.set(c,1);
return a;
}, new Map())
.forEach((value, key, map) => {
keys.push(key);
values.push(value);
});




console.log(keys)
console.log(values)

var aa = [1,3,5,7,3,2,4,6,8,1,3,5,5,2,0,6,5,9,6,3,5,2,5,6,8];
var newArray = {};
for(var element of aa){
if(typeof newArray[element] === 'undefined' || newArray[element] === null){
newArray[element] = 1;
}else{
newArray[element] +=1;
}
}


for ( var element in newArray){
console.log( element +" -> "+ newArray[element]);
}

这个问题是8岁以上,很多很多答案都不是考虑到ES6及其众多优势。

也许对思考更重要的是,当我们创建额外的数组,创建数组的两倍或三倍副本,甚至将数组转换为对象时,垃圾收集/内存管理代码的结果。对于小型应用来说,这些都是微不足道的观察结果,但如果规模化是一个长期目标,那么就要彻底考虑这些问题。

如果您只是需要一个特定数据类型的“计数器”,并且起点是一个数组(我假设您因此想要一个有序列表,并利用数组提供的许多属性和方法),那么您只需简单地遍历array1,并用array1中找到的这些值的值和出现次数填充array2。

就这么简单。

面向对象编程面向对象设计的简单类SimpleCounter (ES6)的示例

class SimpleCounter {


constructor(rawList){ // input array type
this.rawList = rawList;
this.finalList = [];
}


mapValues(){ // returns a new array


this.rawList.forEach(value => {
this.finalList[value] ? this.finalList[value]++ : this.finalList[value] = 1;
});


this.rawList = null; // remove array1 for garbage collection


return this.finalList;


}


}


module.exports = SimpleCounter;

一行ES6解决方案。这么多的答案使用对象作为映射,但我看不到任何人使用实际的地图

const map = arr.reduce((acc, e) => acc.set(e, (acc.get(e) || 0) + 1), new Map());

使用map.keys()来获取唯一的元素

使用map.values()来获取事件

使用map.entries()获取对[元素,频率]

var arr = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4]


const map = arr.reduce((acc, e) => acc.set(e, (acc.get(e) || 0) + 1), new Map());


console.info([...map.keys()])
console.info([...map.values()])
console.info([...map.entries()])

使用具有O (n)时间复杂度的映射的解决方案。

var arr = [2, 2, 2, 2, 2, 4, 5, 5, 5, 9];


const countOccurrences = (arr) => {
const map = {};
for ( var i = 0; i < arr.length; i++ ) {
map[arr[i]] = ~~map[arr[i]] + 1;
}
return map;
}

演示:http://jsfiddle.net/simevidas/bnACW/

使用Lodash

const values = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];
const frequency = _.map(_.groupBy(values), val => ({ value: val[0], frequency: val.length }));
console.log(frequency);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>

给定下面提供的数组:

const array = [ 'a', 'b', 'b', 'c', 'c', 'c' ];

你可以使用这个简单的一行代码来生成一个哈希映射,将一个键链接到它在数组中出现的次数:

const hash = Object.fromEntries([ ...array.reduce((map, key) => map.set(key, (map.get(key) || 0) + 1), new Map()) ]);
// { a: 1, b: 2, c: 3 }

扩大,解释道:

// first, we use reduce to generate a map with values and the amount of times they appear
const map = array.reduce((map, key) => map.set(key, (map.get(key) || 0) + 1), new Map())


// next, we spread this map into an array
const table = [ ...map ];


// finally, we use Object.fromEntries to generate an object based on this entry table
const result = Object.fromEntries(table);

array.reduce代码归@corashina

我知道这个问题是旧的,但我意识到有太少的解决方案,你得到的计数数组要求用最小的代码,所以这是我的

// The initial array we want to count occurences
var initial = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];


// The count array asked for
var count = Array.from(new Set(initial)).map(val => initial.filter(v => v === val).length);


// Outputs [ 3, 5, 1, 1 ]

你可以从初始数组中得到集合

var set = Array.from(new Set(initial));


//set = [5, 2, 9, 4]

2021年的版本

更优雅的方法是使用O(n)时间复杂度的Logical nullish assignment (x ??= y) 结合Array#reduce()

主要思想仍然是使用Array#reduce()将输出聚合为object,以根据searching和amp获得最高性能(时间和空间的复杂性);construct bunches of intermediate arrays像其他答案。

const arr = [2, 2, 2, 2, 2, 4, 5, 5, 5, 9];
const result = arr.reduce((acc, curr) => {
acc[curr] ??= {[curr]: 0};
acc[curr][curr]++;
  

return acc;
}, {});


console.log(Object.values(result));

清洁,重构代码

使用逗号运算符(,)语法。

The comma operator (,)计算它的每个操作数(从左到 返回最后一个操作数的值.

. right)和返回最后一个操作数的值

const arr = [2, 2, 2, 2, 2, 4, 5, 5, 5, 9];
const result = arr.reduce((acc, curr) => (acc[curr] = (acc[curr] || 0) + 1, acc), {});
console.log(result);

输出

{
"2": 5,
"4": 1,
"5": 3,
"9": 1
}

使用reduce波浪号(~)操作符的短版本。

const data = [2, 2, 2, 2, 2, 4, 5, 5, 5, 9];


function freq(nums) {
return nums.reduce((acc, curr) => {
acc[curr] = -~acc[curr];
return acc;
}, {});
}


console.log(freq(data));

似乎问题特别要求有两个结果数组,我还没有看到,所以这是我的解决方案:

const theArray = [1, 3425, 56, 7, 9, 5, 4, 3425, 7, 7, 7];


const uniqueVals = [...new Set(theArray)];
const countPerUniqueValArray = uniqueVals.map(uv => theArray.filter(i => i === uv).length);


console.log(uniqueVals);
console.log(countPerUniqueValArray);


// Expect:
// [1, 3425, 56, 7, 9, 5, 4]
// [1, 2, 1, 4, 1, 1, 1]

const data = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4]
function countAndSort(arr) {
return Object.entries(arr.reduce((prev, curr) => (prev[curr] = ++prev[curr] || 1, prev), {})).sort((a,b) => b[1]-a[1])
}
console.log(countAndSort(data))

返回一个可排序的数组:

let array = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4]
let reducedArray = array.reduce( (acc, curr, _, arr) => {
if (acc.length == 0) acc.push({item: curr, count: 1})
else if (acc.findIndex(f => f.item === curr ) === -1) acc.push({item: curr, count: 1})
else ++acc[acc.findIndex(f => f.item === curr)].count
return acc
}, []);


console.log(reducedArray.sort((a,b) => b.count - a.count ))


/*
Output:
[
{
"item": 2,
"count": 5
},
{
"item": 5,
"count": 3
},
{
"item": 9,
"count": 1
},
{
"item": 4,
"count": 1
}
]


*/