计算JavaScript数组元素的出现次数,并放入一个新的2d数组

Counting the occurrences of JavaScript array elements and put in a new 2d array

本文关键字:数组 2d 一个 数组元素 JavaScript 计算      更新时间:2023-09-26

嗨,我有一个这样的数组

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

我的目标是计算唯一值,并报告其中的任何项,因此结果将是

Array [
   [5, 3],
   [2, 5],
   [9, 1],
   [4, 1]
]

我找到了一个解决方案,可以在这篇文章中找到[计算JavaScript数组元素的出现次数

@Emissary解决方案对我来说是最好的,问题是这个解决方案过去并添加了一些我不需要的新功能,我不能直接回复那个帖子,询问如何只拥有我需要的数组:D

@Emissary添加

console.log(key + ': ' + val)

我的第一个想法是,而不是控制台。log我可以推动二维数组中的每个值,但我不认为这是一个好主意,因为如果我已经很好地理解了@Emissary解决方案,解决方案的第一部分创建正是我需要的数组。

知道如何"隔离"这个特定的数组吗?

这是使用Map的理想情况,因为它通过键进行标识,但在对其进行强制转换时也会转换为该类型的数组:

var a = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];
var result = [...a.reduce( (m, v) => m.set(v, (m.get(v) || 0) + 1), new Map() )];
console.log(result);

注意,每次迭代执行a.filter的解具有O(n²)时间复杂度,而这是O(n)。您可以使用Array.from(a.reduce(....))来代替扩展操作符。

对于较旧的浏览器,您可以使用此变体:

var a = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];
var obj = a.reduce( function (m, v) { return m[v] = (m[v] || 0) + 1, m }, {} ),
    result = [];
for (var key in obj) {
    result.push([+key, obj[key]]);
}
console.log(result);

您可以使用forEach()循环。

var a = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];
var result = []
a.forEach(function(e) {
  if (!this[e]) {
    this[e] = [e, 0];
    result.push(this[e])
  }
  this[e][1] ++
}, {})
console.log(result)

您可以使用ES6的Mapmap来实现,并使用array.from array.from

将其转换回数组。

Map类似于哈希,它维护一个键值对。不是遍历每个元素并维护一个计数,而是创建一个映射并设置每次出现的计数,并将其转换为一个数组,这很容易使用es6

检查这个片段

var a = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];
var myMap2 = new Map();
a.forEach(function(num) {
  if (myMap2.has(num)) {
    var count = myMap2.get(num);
    myMap2.set(num, count + 1);
  } else
    myMap2.set(num, 1);
});
var arr = Array.from(myMap2);
console.log(arr);

希望有所帮助

把它从Map构造函数中拉出来

var a = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];
var aCount = [...new Set(a)].map(
  x => [x, a.filter(y => y === x).length]
);
console.log(aCount);
   

您可以在Emissary的解决方案中使用扩展语法来获得具有所需结果的数组。

var a = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];
var aCount = [... new Map([... new Set(a)].map(
    x => [x, a.filter(y => y === x).length]
))];
console.log(aCount);

值得注意的是,reducespread syntax解决方案在与map结合以转换输出列时,在计算文本(通常是单词包)中的单词出现次数/频率数组时也非常有效:

var r,words="We don't talk anymore'nWe don't talk anymore'nWe don't talk anymore'nLike we used to do'nWe don't love anymore'nWhat was all of it for?'nOh, we don't talk anymore'nLike we used to do'n'nI just heard you found the one you've been looking'nYou've been looking for"
words=words.split(/[''s]+/g);
r=[...words.reduce( (m, v) => m.set(v, ((m.get(v) || 0) + 1)), new Map() )].map(e=>[e[0],e[1]/words.length])
console.log(r)

这是很好的解决方案,但只是为了多样化,您不妨在对结果进行排序时执行以下操作

var a = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4],
thing = a.reduce((p,c) => (p[c] ? p[c]++ : p[c] = 1,p),[])
         .reduce((p,c,i) => c ? (p.push([i,c]),p) : p ,[]);
console.log(thing);

好吧…有人可能会抱怨根据原始数字生成一个巨大的稀疏数组的可能性,但没关系……for in循环负责这个。让我们再来一次…

var  a = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4],
sparse = a.reduce((p,c) => (p[c] ? p[c]++ : p[c] = 1,p),[]),
 dense = [];
for (var key in sparse) dense.push([+key,sparse[key]]);
console.log(dense);