首页 > 解决方案 > 用一个循环查找 JS 数组的最频繁项

问题描述

我创建了一个函数,它使用两个 for 循环查找 JS 数组中最常见的项目,并显示该项目以及数组中有多少次。我怎样才能用一个循环来做到这一点?

var arr=[3, 'a', 'a', 'a', 2, 3, 'a', 3, 'a', 2, 4, 9, 3];

//ta = times appeared / m = max / arrchar = array character
var ta = 1;
var m = 0;
var arrchar;

for (var i=0; i<arr.length; i++)
{
        for (var j=i; j<arr.length; j++)
        {
                if (arr[i] == arr[j])
                 m++;
                if (ta<m)
                {
                  ta=m; 
                  arrchar = arr[i];
                }
        }
        m=0;
}
console.log(arrchar+"("+ta +")") ;

标签: javascriptarrays

解决方案


最简单的方法是计算每个元素的出现次数,按降序排列并获取第一个值

var arr = [3, 'a', 'a', 'a', 2, 3, 'a', 3, 'a', 2, 4, 9, 3];

let findMostFrequent = (arr) => {
  return [...arr.reduce((op, inp) => {
    op.set(inp, (op.get(inp) || 0) + 1)
    return op
  }, new Map())].sort((a, b) => b[1] - a[1])[0][0]
}


console.log(findMostFrequent(arr))


单循环版本

您可以在 reduce 方法中使用数组作为累加器,这里第一个元素是Map跟踪值及其出现,第二个元素是跟踪maxCountand maxValue,根据中的值更改这些值Map

var arr = [3, 'a', 'a', 'a', 2, 3, 'a', 3, 'a', 2, 4, 9, 3];

let findMostFrequent = (arr) => {
  return arr.reduce((op, inp) => {
    op[0].set(inp, (op[0].get(inp) || 0) + 1)
    if(op[0].get(inp) > op[1].maxCount){
      op[1].maxCount = op[0].get(inp)
      op[1].maxValue = inp
    }
    return op
  }, [new Map(), {maxCount:1, maxValue: arr[0]}])[1].maxValue
}


console.log(findMostFrequent(arr))

这可以通过使用两个单独的变量并且仅 Map 作为累加器来进一步简化,因此您无需每次都按索引访问值,请查看 Jhon 的答案中使用名为maxCount和的两个变量的方法max


推荐阅读