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

例如,如果初始数组是:

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

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

5, 2, 9, 4

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

3, 5, 1, 1

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

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

谢谢:)


当前回答

试试这个:

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

其他回答

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

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

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

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 arr = [5,5,5,2,2,2,2,2,2,2,2,9,4]; Const counts = {}; (const num of arr) { Counts [num] = Counts [num] ?计数[num] + 1: 1; } console.log(重要); Console.log(计数[5],计数[2],计数[9],计数[4]);

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

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

如果您想获取成员数组,只需使用keys()函数即可

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

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