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

时间:2016-11-17 21:42:19

标签: javascript arrays

嗨,我有一个像这样的数组

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

我的目标是计算唯一值,并对其中的任何项目进行报告,以便结果很好

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

我找到了一个解决方案,可以在这篇文章中找到 [Counting the occurrences of JavaScript array elements

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

@Emissary添加

  

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

我的第一个想法是,而不是console.log我可以推送2d数组中的每个值,但我认为这不是一个好主意,因为如果我很了解@Emissary解决方案,那么解决方案的第一部分准确创建我需要的数组。

知道如何“隔离”这个特定阵列吗?

7 个答案:

答案 0 :(得分:5)

这是使用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);

答案 1 :(得分:3)

您可以使用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)




答案 2 :(得分:2)

您可以使用ES6的地图map并使用Array.from array.from将其转换回数组

Map类似于hash,它维护一个键值对。而不是遍历每个元素并保持计数,创建一个映射并设置每个事件的计数并将其转换为一个容易使用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);




希望有所帮助

答案 3 :(得分:1)

将其从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);
   




答案 4 :(得分:0)

您可以使用spread syntaxEmissary 的解决方案来获取包含所需结果的数组。

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

答案 5 :(得分:0)

这里提供了很好的解决方案,但只是为了获得多样性,您可以按照以下方式进行排序



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 loop takes care of that。所以让我们再做一次......



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




答案 6 :(得分:0)

值得注意的是,$(document).ready(function() { $('#reservation-sheet').selectable({ filter: 'tr, td', //lets filter to tr and td selecting: function(event, ui) { var selectingItems = $('.ui-selecting', this); var startingRow = selectingItems.first().prop('id'); //starting row id var splitCell = selectingItems.last().prop('id').split('-'); //since we have the row id in the cell id, we can use that to find changes if(splitCell[0] != startingRow) { selectingItems.not(':first').removeClass('ui-selecting'); //remove extra row to keep it at 1 } }, stop: function(event, ui) { var selectedItems = $('.ui-selected', this); var startTime = selectedItems[Object.keys(selectedItems)[1]]; var startTime2 = startTime['id']; //get our starting cell var endTime = selectedItems.last().prop('id'); //get our last cell console.log('send to php: startingTime: '+ startTime2 +' endingTime: '+ endTime); //$.post('contact.php', {sTime: startingTime, eTime: endTime}, function(data, status) { //pop-up window to get name, email and phone number //then submit everything //}); } }); }); reduce解决方案在评估文本中的单词出现次数/频率(通常是单词包)时也非常有效。 spread syntax转换输出列:



map