在一个数组中获取出现次数最高的元素

123

我正在寻找一种优雅的方法来确定JavaScript数组中出现率最高的元素(mode)。

例如,在以下数组中:

['pear', 'apple', 'orange', 'apple']

'apple'元素是最常见的一个。


你可以从这个Stackoverflow问题中借鉴一些想法。https://dev59.com/eXRA5IYBdhLWcg3wvgsb - Nosredna
我没有仔细阅读解决方案,但它们中是否有任何一种考虑了以下细微差别(优化?),基于仅需确定哪个元素具有最多出现次数的要求,而不是最多出现次数是多少...当循环数组时,如果计数可以停止,则差异在最高和次高出现次数之间小于剩余要循环的元素数量,循环可以停止,当前最高值将是最高值。 - Dexygen
这是一个与编程语言无关的问题,位于算法-在大型单词序列中查找前K个频繁单词的最有效方法-堆栈溢出 - user202729
44个回答

0

这个函数是通用的,适用于任何类型的信息。它计算元素出现的次数,然后返回具有最大出现元素的数组。

function mode () {
  var arr = [].slice.call(arguments);
  if ((args.length == 1) && (typeof args[0] === "object")) {
    args = args[0].mode();
  }

  var obj = {};
  for(var i = 0; i < arr.length; i++) {
    if(obj[arr[i]] === undefined) obj[arr[i]] = 1;
    else obj[arr[i]]++;
  }

  var max = 0;
  for (w in obj) {
    if (obj[w] > max) max = obj[w];
  }

  ret_val = [];
  for (w in obj) {
    if (obj[w] == max) ret_val.push(w);
  }

  return ret_val;
}

0
function getData(arr){
  let obj = {}
  let maxElementCount = 0
  let maxEle = ''
  for(let i = 0 ;i<arr.length;i++){
    if(!obj[arr[i]]){
        obj[arr[i]] = 1
    }else{
        obj[arr[i]] += 1
      if(maxElementCount < obj[arr[i]]){
        maxElementCount = obj[arr[i]]
        maxEle = arr[i]
      }
    }
  }
  console.log(maxElementCount, maxEle)
  return obj
}

您可以使用这个简单的方法来获取元素的最大计数。

0
var mode = 0;
var c = 0;
var num = new Array();
var value = 0;
var greatest = 0;
var ct = 0;

注意:ct是数组的长度。
function getMode()
{
    for (var i = 0; i < ct; i++)
    {
        value = num[i];
        if (i != ct)
        {
            while (value == num[i + 1])
            {
                c = c + 1;
                i = i + 1;
            }
        }
        if (c > greatest)
        {
            greatest = c;
            mode = value;
        }
        c = 0;
    }
}

0

// works for all types of data within an array

function findMostRepeated(arr) {
  const itemFrequencyMap = new Map()

  for (let i = 0; i < arr.length; i++) {
    if (itemFrequencyMap.has(arr[i])) {
      itemFrequencyMap.set(arr[i], itemFrequencyMap.get(arr[i]) + 1)
    } else {
      itemFrequencyMap.set(arr[i], 1)
    }
  }

  // console.log(itemFrequencyMap)

  return Array.from(itemFrequencyMap).reduce((item1, item2) =>
    item1[1] > item2[1] ? item1 : item2
  )[0]
}

console.log(findMostRepeated(["pear", "apple", "orange", "apple"]))


0

我猜你有两种方法,都有优点。

排序再计数或者遍历并使用哈希表进行计数。

哈希表很好用,因为一旦处理完成,你还可以得到所有不同的元素。但如果有数百万项且重复率很低,则哈希表可能会占用大量内存。排序再计数的方法将具有更可控的内存占用。


0

const data = ['x','y','x','z',5,2,4,5,2,3,2,'x', { x: 1 }, (x) => x];

function getModeData(data) {
  return data.reduce((a,c) => {
    if(typeof a[c] === "undefined") {
      a[c] = 1;
    } else {
      a[c]++;
    }
    if(
      typeof a.mode === "undefined" ||
      (typeof a.mode !== "undefined") && a.mode.occurrences < a[c]
    ) {
      a.mode = {
        elem: c,
        occurrences: a[c]
      }
    }
    return a;
  }, { mode: undefined });
}

const { mode: { elem, occurrences }, ...totals } = getModeData(data);

console.log(`The mode is ${elem} with ${occurrences} occurrences`);

console.log('The totals are:');
console.log(totals)


0

//const arr = [1, 2, 4, 3, 5, 1, 2, 3, 3];
const arr = ['pear', 'apple', 'orange', 'apple'];

// init max occurance element
let maxOcc = {'element': null, occured: 0};

// to find occurances
const res = arr.reduce((acc, el) => {
    acc[el] = acc[el] ? acc[el]+1 : 1;
    if(acc[el]> maxOcc.occured){
        maxOcc = { 'element': el, occured: acc[el] };
    }
    return acc;
}, {});

console.log(maxOcc);


0

已经有很多答案了,但我想和你分享一下我的想法 :) 不能说这个解决方案依赖于任何边缘情况,但无论如何)

const getMostFrequentElement = ( arr ) => {
  const counterSymbolKey = 'counter'
  const mostFrequentSymbolKey = 'mostFrequentKey'

  const result = arr.reduce( ( acc, cur ) => {
    acc[ cur ] = acc[ cur ] ? acc[ cur ] + 1 : 1

    if ( acc[ cur ] > acc[ Symbol.for( counterSymbolKey ) ] ) {
      acc[ Symbol.for( mostFrequentSymbolKey ) ] = cur
      acc[ Symbol.for( counterSymbolKey ) ] = acc[ cur ]
    }

    return acc
  }, {
    [ Symbol.for( mostFrequentSymbolKey ) ]: null,
    [ Symbol.for( counterSymbolKey ) ]: 0
  } )

  return result[ Symbol.for( mostFrequentSymbolKey ) ]
}

希望对某些人有所帮助。

0

你可以用O(n)的复杂度解决它。

var arr = [1,3,54,56,6,6,1,6];
var obj = {};

/* first convert the array in to object with unique elements and number of times each element is repeated */
for(var i = 0; i < arr.length; i++)
{
   var x = arr[i];
   if(!obj[x])
     obj[x] = 1;
   else 
     obj[x]++;
}

console.log(obj);//just for reference

/* now traverse the object to get the element */
var index = 0;
var max = 0;

for(var obIndex in obj)
{
  if(obj[obIndex] > max)
  {
    max = obj[obIndex];
    index = obIndex;
  }
}
console.log(index+" got maximum time repeated, with "+ max +" times" );

只需复制并粘贴代码到Chrome控制台中即可运行上述代码。

0

这是我的方法。我首先尝试对数据进行分组。

const _ = require("underscore")

var test  = [ 1, 1, 2, 1 ];
var groupResult = _.groupBy(test, (e)=> e);

groupResult 应该是:

{
  1: [1, 1, 1]
  2: [2] 
}

然后找到具有最长数组的属性

function findMax(groupResult){
   var maxArr = []
   var max;
   for(var item in groupResult){
     if(!max) { 
        max = { value:item, count: groupResult[item].length } ; 
        maxArr.push(max); 
        continue;
     }
     if(max.count < groupResult[item].length){ 
        maxArr = [];
        max = { value:item, count: groupResult[item].length }
        maxArr.push(max)
     } else if(max === groupResult[item].length)
        maxArr.push({ value:item, count: groupResult[item].length })
   }
   return maxArr;
}

完整的代码如下所示

const _ = require("underscore")

var test  = [ 1, 1, 2, 1 ];
var groupResult= _.groupBy(test, (e)=> e);
console.log(findMax(groupResult)[0].value);

function findMax(groupResult){
   var maxArr = []
   var max;
   for(var item in groupResult){
     if(!max) { 
        max = { value:item, count: groupResult[item].length } ; 
        maxArr.push(max); 
        continue;
     }
     if(max.count < groupResult[item].length){ 
        maxArr = [];
        max = { value:item, count: groupResult[item].length }
        maxArr.push(max)
     } else if(max === groupResult[item].length)
        maxArr.push({ value:item, count: groupResult[item].length })
   }
   return maxArr;
}

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