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

例如,如果初始数组是:

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

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

5, 2, 9, 4

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

3, 5, 1, 1

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

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

谢谢:)


当前回答

使用滤镜很简单

在本例中,我们简单地分配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

其他回答

编辑2020年:这是一个相当老的答案(9年)。扩展本机原型总是会引起讨论。尽管我认为程序员可以自由选择自己的编程风格,这里有一个(更现代的)方法来解决这个问题,而不需要扩展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; }

旧的(2011年)答案是:你可以扩展Array。原型,像这样:

{ 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; }

所以这里是我如何做的一些最新的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或对象进行计数(与对象不同,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)

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

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

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

使用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/