Javascript 习惯性地查找给定值在数组中的出现次数

Javascript 习惯性地查找给定值在数组中的出现次数,javascript,arrays,Javascript,Arrays,我有一个重复值的数组。我想找出任何给定值的出现次数 例如,如果我有一个定义为so的数组:var-dataset=[2,2,4,2,6,4,7,8],我要查找数组中某个值的出现次数。也就是说,程序应该显示如果我有3次出现值2,1次出现值6,依此类推 最惯用/最优雅的方法是什么?因为使用了Array.filter var dataset = [2,2,4,2,6,4,7,8]; var search = 2; var occurrences = dataset.filter(function(val

我有一个重复值的数组。我想找出任何给定值的出现次数

例如,如果我有一个定义为so的数组:
var-dataset=[2,2,4,2,6,4,7,8],我要查找数组中某个值的出现次数。也就是说,程序应该显示如果我有3次出现值
2
,1次出现值
6
,依此类推


最惯用/最优雅的方法是什么?

因为使用了
Array.filter

var dataset = [2,2,4,2,6,4,7,8];
var search = 2;
var occurrences = dataset.filter(function(val) {
    return val === search;
}).length;
console.log(occurrences); // 3

使用法线循环,可以一致可靠地找到引用:

const dataset = [2,2,4,2,6,4,7,8];

function getNumMatches(array, valToFind) {
    let numMatches = 0;
    for (let i = 0, j = array.length; i < j; i += 1) {
        if (array[i] === valToFind) {
            numMatches += 1;
        }
    }
    return numMatches;
}

alert(getNumMatches(dataset, 2)); // should alert 3

演示:

reduce
在这里比
filter
更合适,因为它不只是为了计数而构建临时数组

var数据集=[2,2,4,2,6,4,7,8];
var搜索=2;
var count=dataset.reduce(函数(n,val){
返回n+(val==搜索);
}, 0);

控制台日志(计数)以下是一种同时显示所有计数的方法:

var dataset = [2, 2, 4, 2, 6, 4, 7, 8];
var counts = {}, i, value;
for (i = 0; i < dataset.length; i++) {
    value = dataset[i];
    if (typeof counts[value] === "undefined") {
        counts[value] = 1;
    } else {
        counts[value]++;
    }
}
console.log(counts);
// Object {
//    2: 3,
//    4: 2,
//    6: 1,
//    7: 1,
//    8: 1
//}
var数据集=[2,2,4,2,6,4,7,8];
变量计数={},i,值;
对于(i=0;i
您可以使用
JavaScript 1.8中的
array.reduce(回调[,initialValue])
方法

var dataset = [2,2,4,2,6,4,7,8],
    dataWithCount = dataset.reduce( function( o , v ) {

        if ( ! o[ v ] ) {
            o[ v ] = 1 ;  
        }  else {
            o[ v ] = o[ v ] + 1;
        }      

        return o ;    

    }, {} );

// print data with count.
for( var i in  dataWithCount ){
     console.log( i + 'occured ' + dataWithCount[i] + 'times ' ); 
}

// find one number
var search = 2,
    count = dataWithCount[ search ] || 0;

您可以使用reduce在一行中计算数组中的所有项

[].reduce((a,b) => (a[b] = a[b] + 1 || 1) && a, {})
这将生成一个对象,其键是数组中不同的元素,值是数组中元素出现的计数。然后,您可以通过访问对象上的相应键来访问一个或多个计数

例如,如果要将上述内容包装到名为
count()
的函数中:


我发现,更有用的方法是,最终得到一个对象列表,其中包含一个用于计数的键和一个用于计数的键:

const data = [2,2,4,2,6,4,7,8]
let counted = []
for (var c of data) {
  const alreadyCounted = counted.map(c => c.name)
  if (alreadyCounted.includes(c)) {
    counted[alreadyCounted.indexOf(c)].count += 1
  } else {
    counted.push({ 'name': c, 'count': 1})
  }
}
console.log(counted)
返回:

[ { name: 2, count: 3 },
  { name: 4, count: 2 },
  { name: 6, count: 1 },
  { name: 7, count: 1 },
  { name: 8, count: 1 } ]

这不是最干净的方法,如果有人知道如何使用
reduce
获得相同的结果,请告诉我。然而,它确实产生了一个相当容易处理的结果。

首先,您可以通过线性搜索使用蛮力解决方案

public int LinearSearchcount(int[] A, int data){
  int count=0;
  for(int i=0;i<A.length;i++) {
    if(A[i]==data) count++;
  }
  return count;
}
public int LinearSearchcount(int[]A,int数据){
整数计数=0;

对于(int i=0;i@thg435我尝试使用此方法,结果得到了一个未定义的值……而且,
reduce
方法是否仍然保留数组?我希望保持数组不变。@Bagavatu:发布代码/小提琴。不,reduce不会更改数组。@Narshe:添加了一个Typescript示例。这是一个非常快速的响应。非常感谢。我知道了我还有一个问题。新版本中密钥可为null的选项已丢失。不确定是否有意使用:
constructor(iter,key=null)
this.key=key | |(x=>x)
@Narshe:x=>x
类型为
T=>T
,而类的设计目的是接受
T=>CounterKey
。我建议将其分为两类:just
Counter
(不带回调)和
keyccounter
(带强制回调)。或者,更短:
executions=dataset.filter(v=>v==search).length
他检查每个循环是否已经存在该键。如果是,则将当前的值增加1。如果不是,则为该键插入1。+1用于包装在语义上可以理解和可读的函数中。尽管我将其称为
getNumMatches
getNumOccurrences
findOccurrences
听起来像是e尝试返回事件本身(一个数组),而不是返回事件的数量(一个数字)。此外,正如其他人所提到的,您可以传入谓词函数而不是值来测试匹配情况。演示:@AdamZerner同意,感谢您的输入。更新了您的建议。这是最好的答案。
function count(arr) {
  return arr.reduce((a,b) => (a[b] = a[b] + 1 || 1) && a, {})
}

count(['example'])          // { example: 1 }
count([2,2,4,2,6,4,7,8])[2] // 3
const data = [2,2,4,2,6,4,7,8]
let counted = []
for (var c of data) {
  const alreadyCounted = counted.map(c => c.name)
  if (alreadyCounted.includes(c)) {
    counted[alreadyCounted.indexOf(c)].count += 1
  } else {
    counted.push({ 'name': c, 'count': 1})
  }
}
console.log(counted)
[ { name: 2, count: 3 },
  { name: 4, count: 2 },
  { name: 6, count: 1 },
  { name: 7, count: 1 },
  { name: 8, count: 1 } ]
public int LinearSearchcount(int[] A, int data){
  int count=0;
  for(int i=0;i<A.length;i++) {
    if(A[i]==data) count++;
  }
  return count;
}