统计数组元素出现次数/频率

352

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

例如,如果初始数组如下:

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

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

5, 2, 9, 4
第二个数组将包含该元素在初始数组中出现的次数:
3, 5, 1, 1
因为数字5出现了三次,数字2出现了五次,数字9和4各出现了一次。
我已经搜索过很多解决方案,但似乎没有一个可行的,并且我自己尝试的所有方法都变得非常复杂。任何帮助将不胜感激!
谢谢 :)

16
如果你只需要判断一个值是否仅出现一次(而不是两次或更多),你可以使用 if (arr.indexOf(value) == arr.lastIndexOf(value)) - Rodrigo
2
我们可以使用 ramda.js 来轻松实现这一点。R.countBy(r=> r)(ary)``` - Eshwar Prasad Yaddanapudi
arr.filter(x => x===5).length 会返回 3,表示数组中有 '3' 个数字 '5'。 - noobninja
假设我的响应是对象数组。 - Ajay
42个回答

1
你可以通过扩展数组中的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

{{链接1:Gist}}


编辑

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

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

而你的第二个数组,使用Array#count将出现次数转换为Array#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}

0

这里有一种方法可以计算对象数组中的出现次数。它还将第一个数组的内容放入新数组中以对值进行排序,以便不破坏原始数组中的顺序。然后使用递归函数来遍历每个元素并计算数组中每个对象的数量属性。

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

0
我在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;
}

0

看起来问题明确要求有两个结果数组,这是我没有见过的,所以这是我的解决方案:

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]

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

0

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


返回格式似乎相当笨拙——一个列表的列表,其中每个内部列表都是一个键和计数。 - idbrii

0

让我们使用Reduce方法来统计数组中元素出现的次数:

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

const uniqueIntArray = numberArray.reduce((x: any, y: any) => ((x[y] = (x[y] || 0) + 1 ), x), {})

console.log('uniqueIntArray ', uniqueIntArray); { "2": 5, "4": 1, "5": 3, "9": 1 }


0

0

<!DOCTYPE html>
<html>
<body>

<script>
const findOccurance = (arr) => {
let resultObj={};
let sortedArr = arr.sort();
let uniqueArrVal = [...new Set(sortedArr)]

uniqueArrVal.forEach(e=> resultObj[e]=(sortedArr.lastIndexOf(e)-sortedArr.indexOf(e))+1)
return resultObj;
}

console.log(findOccurance (['a','b','a']))
console.log(findOccurance ([1,98,5,1,6,'a','f','a',98]))
</script>

</body>
</html> 

如果你想要以数字作为键,计数作为值的输出(例如)对于输入['a','b','a']返回一个像这样的对象{a:1,b:2},那么这是代码。
    const findOccurance = (arr) => {
    let resultObj={};
    let sortedArr = arr.sort();
    let uniqueArrVal = [...new Set(sortedArr)]
    
    uniqueArrVal.forEach(e=> resultObj[e]=(sortedArr.lastIndexOf(e)-sortedArr.indexOf(e))+1)
    return resultObj;
    }
console.log(findOccurance (['a','b','a']))
console.log(findOccurance ([1,98,5,1,6,'a','f','a',98]))

-1

这是一种经典的老派方法,用于计算数组。

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

如果您想要按字母顺序排序,可以先进行排序,但如果您想保留数据输入的顺序,请尝试这个方法。嵌套循环可能比本页面上的其他方法慢一些。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接