Obtenha o elemento com a maior ocorrência em uma matriz

87

Estou procurando uma maneira elegante de determinar qual elemento tem a maior ocorrência ( modo ) em uma matriz JavaScript.

Por exemplo, em

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

o 'apple'elemento é o mais frequente.

torno
fonte
Você pode adaptar algumas ideias desta questão Stackoverflow. stackoverflow.com/questions/840781/…
Nosredna
Eu não li as soluções muito atentamente, mas alguma delas incorpora a seguinte nuance (otimização?), Com base na necessidade de apenas determinar qual elemento tem mais ocorrências, ao invés de quantas ocorrências são mais .... e essa nuance é, conforme a matriz é repetida, a contagem pode parar quando a diferença entre a maior e a segunda maior ocorrência for menor que o número de elementos restantes para fazer o loop, o loop pode cessar, a corrente mais alta será a mais alta
Dexygen
1
Além disso, essas soluções não parecem levar em conta os laços.
Dexygen
1
Caso você esteja procurando outra solução (que é um pouco menor) stackoverflow.com/questions/40410470/…
daanvanham

Respostas:

95

Este é apenas o modo. Esta é uma solução rápida e não otimizada . Deve ser O (n).

function mode(array)
{
    if(array.length == 0)
        return null;
    var modeMap = {};
    var maxEl = array[0], maxCount = 1;
    for(var i = 0; i < array.length; i++)
    {
        var el = array[i];
        if(modeMap[el] == null)
            modeMap[el] = 1;
        else
            modeMap[el]++;  
        if(modeMap[el] > maxCount)
        {
            maxEl = el;
            maxCount = modeMap[el];
        }
    }
    return maxEl;
}
Matthew Flaschen
fonte
1
Legal ... mas só funciona para strings - não necessariamente uma limitação, mas algo a se considerar.
James
Muito obrigado, não esperava uma solução completa. Funciona em strings e números com apenas uma única passagem, o que é bastante bom.
vise
1
Eu adicionei uma versão desse algoritmo para lidar com empates.
samandmoore de
3
Tive que substituir `f (modeMap [el] == null) por if (! ModeMap [el]), pois estava mergulhando em um número estranho ao passar [2, 3, 3] porque modeMap [el] era indefinido e não nulo.
Naz de
1
Acho que é razoável ter um desempatador, que neste caso é o elemento que vem primeiro no array. Mas você pode facilmente alterar esse algoritmo para fornecer a você cada empate para a maioria.
Wylliam Judd
63

Houve alguns desenvolvimentos em javascript desde 2009 - pensei em adicionar outra opção. Estou menos preocupado com a eficiência até que seja realmente um problema, então minha definição de código "elegante" (conforme estipulado pelo OP) favorece a legibilidade - o que é obviamente subjetivo ...

function mode(arr){
    return arr.sort((a,b) =>
          arr.filter(v => v===a).length
        - arr.filter(v => v===b).length
    ).pop();
}

mode(['pear', 'apple', 'orange', 'apple']); // apple

Neste exemplo específico, se dois ou mais elementos do conjunto tiverem ocorrências iguais, aquele que aparecer por último na matriz será retornado. Também vale a pena ressaltar que ele modificará seu array original - o que pode ser evitado se você desejar com uma Array.slicechamada prévia.


Edit: atualizou o exemplo com algumas setas grossas ES6 porque 2015 aconteceu e eu acho que elas estão bonitas ... Se você está preocupado com a compatibilidade com versões anteriores, você pode encontrar isso no histórico de revisão .

Emissário
fonte
Isso é ótimo! Agora, como você retornaria várias respostas se houver mais de um item na matriz que ocorre igual a outro?
Crystal
É ingênuo porque assume que o modo é único, se você exigir que ele retorne mais de um, então você precisa manter um registro da contagem total para cada item que não parece tão bonito ... você pode tentar algo assim , é simplista porque só funcionará com valores primitivos (mas você pode adaptá-lo ainda mais, se necessário).
Emissário
15
Se este não é um código elegante, não sei o que é. É como um anúncio de programação funcional.
Sam H.
1
@GoranJakovljevic Você pode ser mais específico? Eu imagino que sejam as funções de seta ES6 - você tentou o exemplo compatível com versões anteriores no histórico de revisão?
Emissário de
Você está correto, suas funções de seta. Sim, para trás funciona muito bem.
Goran Jakovljevic
38

De acordo com o George Jempty'spedido para ter o algoritmo responsável pelos empates, proponho uma versão modificada do Matthew Flaschen'salgoritmo.

function modeString(array) {
  if (array.length == 0) return null;

  var modeMap = {},
    maxEl = array[0],
    maxCount = 1;

  for (var i = 0; i < array.length; i++) {
    var el = array[i];

    if (modeMap[el] == null) modeMap[el] = 1;
    else modeMap[el]++;

    if (modeMap[el] > maxCount) {
      maxEl = el;
      maxCount = modeMap[el];
    } else if (modeMap[el] == maxCount) {
      maxEl += "&" + el;
      maxCount = modeMap[el];
    }
  }
  return maxEl;
}

Isso agora retornará uma string com o (s) elemento (s) de modo delimitado (s) por um &símbolo. Quando o resultado é recebido, ele pode ser dividido naquele &elemento e você tem seu (s) modo (s).

Outra opção seria retornar uma matriz de elemento (s) de modo como:

function modeArray(array) {
  if (array.length == 0) return null;
  var modeMap = {},
    maxCount = 1,
    modes = [];

  for (var i = 0; i < array.length; i++) {
    var el = array[i];

    if (modeMap[el] == null) modeMap[el] = 1;
    else modeMap[el]++;

    if (modeMap[el] > maxCount) {
      modes = [el];
      maxCount = modeMap[el];
    } else if (modeMap[el] == maxCount) {
      modes.push(el);
      maxCount = modeMap[el];
    }
  }
  return modes;
}

No exemplo acima, você seria capaz de manipular o resultado da função como um array de modos.

Samandmoore
fonte
1
No segundo exemplo (o da matriz); você não precisa definir modesa [array[0]]como valor inicial. Isso garantirá que você tenha duplicatas em modes. Isso deve funcionarvar modes = []
vdclouis
1
Isso é ótimo! No entanto, quando eu testo isso com uma matriz com dois valores diferentes, ele retorna o primeiro item da matriz duas vezes. Não sei por que isso está acontecendo ...
Cristal
@xgrioux faça a mudança que vdclouis recomenda para combater esse bug. ou seja, altere [array [0]] para [].
Dave Haigh de
recomendar a alteração das instâncias de ==para ===impor igualdade estrita
Len Joseph
16

Com base na resposta ES6 + do Emissário , você poderia usar Array.prototype.reducepara fazer sua comparação (ao invés de classificar, estalar e potencialmente transformar seu array), o que eu acho que parece bastante inteligente.

const mode = (myArray) =>
  myArray.reduce(
    (a,b,i,arr)=>
     (arr.filter(v=>v===a).length>=arr.filter(v=>v===b).length?a:b),
    null)

Estou padronizando para null, o que nem sempre fornecerá uma resposta verdadeira se null for uma opção possível pela qual você está filtrando, talvez esse possa ser um segundo argumento opcional

A desvantagem, como com várias outras soluções, é que ele não lida com 'estados de desenho', mas isso ainda poderia ser alcançado com uma função de redução um pouco mais envolvida.

Davidsharp
fonte
14
a=['pear', 'apple', 'orange', 'apple'];
b={};
max='', maxi=0;
for(let k of a) {
  if(b[k]) b[k]++; else b[k]=1;
  if(maxi < b[k]) { max=k; maxi=b[k] }
}
Pensador
fonte
Ainda é O (n), mas usa desnecessariamente duas passagens.
Matthew Flaschen
2
Como o JavaScript é transmitido, é sempre interessante ver pequenas soluções.
Nosredna
Lol 2 menos para a solução adequada;] Corrigi desnecessariamente duas passagens, estava fazendo rápido, mas ainda funciona e ainda é a solução mais curta.
Thinker
cada acesso a b leva pelo menos log (len (b)), então O (n) pode ser um pouco otimista
Nicolas78
nicolas78: Se a matriz for pequena, não importa. Portanto, depende do seu projeto.
Thinker
7

Como estou usando essa função como um questionário para os entrevistadores, posto minha solução:

const highest = arr => (arr || []).reduce( ( acc, el ) => {
  acc.k[el] = acc.k[el] ? acc.k[el] + 1 : 1
  acc.max = acc.max ? acc.max < acc.k[el] ? el : acc.max : el
  return acc  
}, { k:{} }).max

const test = [0,1,2,3,4,2,3,1,0,3,2,2,2,3,3,2]
console.log(highest(test))
perusopersonale
fonte
6

Tentando uma abordagem declarativa aqui. Essa solução cria um objeto para registrar as ocorrências de cada palavra. Em seguida, filtra o objeto em uma matriz, comparando o total de ocorrências de cada palavra com o valor mais alto encontrado no objeto.

const arr = ['hello', 'world', 'hello', 'again'];

const tally = (acc, x) => { 

  if (! acc[x]) { 
    acc[x] = 1;
    return acc;
  } 

  acc[x] += 1;
  return acc;
};

const totals = arr.reduce(tally, {});

const keys = Object.keys(totals);

const values = keys.map(x => totals[x]);

const results = keys.filter(x => totals[x] === Math.max(...values));
Corey Clark
fonte
Explique sua resposta, por favor
Haris
Eu evitaria calcular o máximo no loop de filtro e removeria a instrução do mapa de chaves para valores. Embora essa resposta não seja a de melhor desempenho, não é tão ruim quanto filtrar no redutor e é imho agradável e legível. const maxValue = Math.max (... Object.values ​​(totals)); resultados const = keys.filter (x => totais [x] === maxValue);
milesaron
3

Hora de outra solução:

function getMaxOccurrence(arr) {
    var o = {}, maxCount = 0, maxValue, m;
    for (var i=0, iLen=arr.length; i<iLen; i++) {
        m = arr[i];

        if (!o.hasOwnProperty(m)) {
            o[m] = 0;
        }
        ++o[m];

        if (o[m] > maxCount) {
            maxCount = o[m];
            maxValue = m;
        }
    }
    return maxValue;
}

Se a brevidade for importante (não), então:

function getMaxOccurrence(a) {
    var o = {}, mC = 0, mV, m;
    for (var i=0, iL=a.length; i<iL; i++) {
        m = a[i];
        o.hasOwnProperty(m)? ++o[m] : o[m] = 1;
        if (o[m] > mC) mC = o[m], mV = m;
    }
    return mV;
}

Se membros inexistentes devem ser evitados (por exemplo, matriz esparsa), um teste hasOwnProperty adicional é necessário:

function getMaxOccurrence(a) {
    var o = {}, mC = 0, mV, m;
    for (var i=0, iL=a.length; i<iL; i++) {
        if (a.hasOwnProperty(i)) {
            m = a[i];
            o.hasOwnProperty(m)? ++o[m] : o[m] = 1;
            if (o[m] > mC) mC = o[m], mV = m;
        }
    }
    return mV;
}

getMaxOccurrence([,,,,,1,1]); // 1

Outras respostas aqui retornarão indefinidas .

RobG
fonte
@ Jonah — a brevidade, por si só, é inútil e geralmente torna o código mais difícil de ler e manter. É claro que um código mais detalhado não é necessariamente melhor apenas por ser mais longo. Mas esses critérios, por si só, são evitados por medidas muito mais importantes, como clareza e facilidade de manutenção.
RobG
Obviamente, a brevidade enigmática e densa nunca é o objetivo. Mas em geral, dadas duas versões do mesmo código com densidade aproximadamente igual, a mais curta é geralmente mais clara e melhor. Não estou dizendo que é uma regra , mas a correlação é forte. Na verdade, eu diria que não há outro único indicador tão altamente correlacionada com a legibilidade. É por isso que todo programador adora excluir código. É por isso que a maioria das reescritas no Code Review são mais curtas do que o original.
Jonah
3

Outra solução JS de: https://www.w3resource.com/javascript-exercises/javascript-array-exercise-8.php

Também pode tentar:

let arr =['pear', 'apple', 'orange', 'apple'];

function findMostFrequent(arr) {
  let mf = 1;
  let m = 0;
  let item;

  for (let i = 0; i < arr.length; i++) {
    for (let j = i; j < arr.length; j++) {
      if (arr[i] == arr[j]) {
        m++;
        if (m > mf) {
          mf = m;
          item = arr[i];
        }
      }
    }
    m = 0;
  }

  return item;
}

findMostFrequent(arr); // apple
AugustoM
fonte
3

Aqui está outra maneira ES6 de fazer isso com complexidade O (n)

const result = Object.entries(
    ['pear', 'apple', 'orange', 'apple'].reduce((previous, current) => {
        if (previous[current] === undefined) previous[current] = 1;
        else previous[current]++;
        return previous;
    }, {})).reduce((previous, current) => (current[1] >= previous[1] ? current : previous))[0];
console.log("Max value : " + result);
Nabil Shahid
fonte
2
function mode(arr){
  return arr.reduce(function(counts,key){
    var curCount = (counts[key+''] || 0) + 1;
    counts[key+''] = curCount;
    if (curCount > counts.max) { counts.max = curCount; counts.mode = key; }
    return counts;
  }, {max:0, mode: null}).mode
}
Jonah
fonte
O problema com esta solução é que as palavras "max" e "modo" não contam, pois fazem parte da lógica do mapa ...
Pablo
2

Aqui está minha solução para este problema, mas com números e usando o novo recurso 'Definir'. Não tem muito desempenho, mas definitivamente me diverti muito escrevendo isso e ele suporta vários valores máximos.

const mode = (arr) => [...new Set(arr)]
  .map((value) => [value, arr.filter((v) => v === value).length])
  .sort((a,b) => a[1]-b[1])
  .reverse()
  .filter((value, i, a) => a.indexOf(value) === i)
  .filter((v, i, a) => v[1] === a[0][1])
  .map((v) => v[0])

mode([1,2,3,3]) // [3]
mode([1,1,1,1,2,2,2,2,3,3,3]) // [1,2]

A propósito, não use isso para produção, esta é apenas uma ilustração de como você pode resolver isso apenas com as funções ES6 e Array.

Anjuna5
fonte
2

Aqui está minha solução: -

function frequent(number){
    var count = 0;
    var sortedNumber = number.sort();
    var start = number[0], item;
    for(var i = 0 ;  i < sortedNumber.length; i++){
      if(start === sortedNumber[i] || sortedNumber[i] === sortedNumber[i+1]){
         item = sortedNumber[i]
      }
    }
    return item
  
}

   console.log( frequent(['pear', 'apple', 'orange', 'apple']))

Meheret
fonte
2

Por uma questão de código realmente fácil de ler e sustentável, compartilho isto:

function getMaxOcurrences(arr = []) {
  let item = arr[0];
  let ocurrencesMap = {};

  for (let i in arr) {
    const current = arr[i];

    if (ocurrencesMap[current]) ocurrencesMap[current]++;
    else ocurrencesMap[current] = 1;

    if (ocurrencesMap[item] < ocurrencesMap[current]) item = current;
  }

  return { 
    item: item, 
    ocurrences: ocurrencesMap[item]
  };
}

Espero que ajude alguém;)!

Eliecer Chicott
fonte
2

Esta solução pode retornar vários elementos de uma matriz em caso de empate. Por exemplo, um array

arr = [ 3, 4, 3, 6, 4, ];

tem dois valores de modo: 3e 6.

Aqui está a solução.

function find_mode(arr) {
    var max = 0;
    var maxarr = [];
    var counter = [];
    var maxarr = [];

    arr.forEach(function(){
       counter.push(0);
    });

    for(var i = 0;i<arr.length;i++){
       for(var j=0;j<arr.length;j++){
            if(arr[i]==arr[j])counter[i]++; 
       }
    } 


    max=this.arrayMax(counter);   
  
    for(var i = 0;i<arr.length;i++){
         if(counter[i]==max)maxarr.push(arr[i]);
    }

    var unique = maxarr.filter( this.onlyUnique );
    return unique;

  };


function arrayMax(arr) {
      var len = arr.length, max = -Infinity;
      while (len--) {
              if (arr[len] > max) {
              max = arr[len];
              }
      }
  return max;
 };

 function onlyUnique(value, index, self) {
       return self.indexOf(value) === index;
 }
Reza
fonte
1
var mode = 0;
var c = 0;
var num = new Array();
var value = 0;
var greatest = 0;
var ct = 0;

Nota: ct é o comprimento da matriz.

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;
    }
}
Kingsley Nnoruka
fonte
1
const mode = (str) => {
  return str
    .split(' ')
    .reduce((data, key) => {
      let counter = data.map[key] + 1 || 1
      data.map[key] = counter

      if (counter > data.counter) {
        data.counter = counter
        data.mode = key
      }

      return data
    }, {
      counter: 0,
      mode: null,
      map: {}
    })
    .mode
}

console.log(mode('the t-rex is the greatest of them all'))
Pablo
fonte
1
function mode(array){
    var set = Array.from(new Set(array));
    var counts = set.map(a=>array.filter(b=>b==a).length);
    var indices = counts.map((a,b)=>Math.max(...counts)===a?b:0).filter(b=>b!==0);
    var mode = indices.map(a=>set[a]);
    return mode;
}
ido klein
fonte
1

Experimente também, isso não leva em conta a versão do navegador.

function mode(arr){
var a = [],b = 0,occurrence;
    for(var i = 0; i < arr.length;i++){
    if(a[arr[i]] != undefined){
        a[arr[i]]++;
    }else{
        a[arr[i]] = 1;
    }
    }
    for(var key in a){
    if(a[key] > b){
        b = a[key];
        occurrence = key;
    }
    }
return occurrence;
}
alert(mode(['segunda','terça','terca','segunda','terça','segunda']));

Observe que esta função retorna a última ocorrência na matriz quando 2 ou mais entradas aparecem o mesmo número de vezes!

Marcelo
fonte
1
// O(n)
var arr = [1, 2, 3, 2, 3, 3, 5, 6];
var duplicates = {};
max = '';
maxi = 0;
arr.forEach((el) => {
    duplicates[el] = duplicates[el] + 1 || 1;
  if (maxi < duplicates[el]) {
    max = el;
    maxi = duplicates[el];
  }
});
console.log(max);
indrajeet
fonte
1

Esta é a versão moderna usando mapas integrados (portanto, funciona em mais do que coisas que podem ser convertidas em strings exclusivas):

'use strict';

const histogram = iterable => {
    const result = new Map();

    for (const x of iterable) {
        result.set(x, (result.get(x) || 0) + 1);
    }

    return result;
};

const mostCommon = iterable => {
    let maxCount = 0;
    let maxKey;

    for (const [key, count] of histogram(iterable)) {
        if (count > maxCount) {
            maxCount = count;
            maxKey = key;
        }
    }

    return maxKey;
};

console.log(mostCommon(['pear', 'apple', 'orange', 'apple']));

Ry-
fonte
0

Eu acho que você tem duas abordagens. Ambos têm vantagens.

Classifique e conte ou faça um loop e use uma tabela hash para fazer a contagem para você.

A tabela de hash é boa porque, depois de concluir o processamento, você também terá todos os elementos distintos. No entanto, se você tivesse milhões de itens, a tabela hash poderia acabar usando muita memória se a taxa de duplicação for baixa. A abordagem de classificação e contagem teria uma pegada de memória muito mais controlável.

Steve Sheldon
fonte
0
var array = [1, 3, 6, 6, 6, 6, 7, 7, 12, 12, 17],
    c = {}, // counters
    s = []; // sortable array

for (var i=0; i<array.length; i++) {
    c[array[i]] = c[array[i]] || 0; // initialize
    c[array[i]]++;
} // count occurrences

for (var key in c) {
    s.push([key, c[key]])
} // build sortable array from counters

s.sort(function(a, b) {return b[1]-a[1];});

var firstMode = s[0][0];
console.log(firstMode);
David Rosson
fonte
0

Você pode tentar isto:

 // using splice()   
 // get the element with the highest occurence in an array
    function mc(a) {
      var us = [], l;
      // find all the unique elements in the array
      a.forEach(function (v) {
        if (us.indexOf(v) === -1) {
          us.push(v);
        }
      });
      l = us.length;
      while (true) {
        for (var i = 0; i < l; i ++) {
          if (a.indexOf(us[i]) === -1) {
            continue;
          } else if (a.indexOf(us[i]) != -1 && a.length > 1) {
            // just delete it once at a time
            a.splice(a.indexOf(us[i]), 1);
          } else {
            // default to last one
            return a[0];
          }
        }
      }
    }

// using string.match method
function su(a) {
    var s = a.join(),
            uelms = [],
            r = {},
            l,
            i,
            m;

    a.forEach(function (v) {
        if (uelms.indexOf(v) === -1) {
            uelms.push(v);
        }
    });

    l = uelms.length;

    // use match to calculate occurance times
    for (i = 0; i < l; i ++) {
        r[uelms[i]] = s.match(new RegExp(uelms[i], 'g')).length;
    }

    m = uelms[0];
    for (var p in r) {
        if (r[p] > r[m]) {
            m = p;
        } else {
            continue;
        }
    }

    return m;
}
void4096
fonte
0

Você poderia resolvê-lo em complexidade 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" );

Basta copiar e colar no console do Chrome para executar o código acima.

Sandeep Gantait
fonte
0

Esta função é uma função genérica para todo tipo de informação. Ele conta a ocorrência dos elementos e retorna a matriz com o máximo de elementos ocorridos.

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;
}
רונן ברברמן
fonte
0
function mode(){
  var input = $("input").val().split(",");
  var mode = [];
  var m = [];
  var p = [];
    for(var x = 0;x< input.length;x++){
      if(m.indexOf(input[x])==-1){
        m[m.length]=input[x];
    }}
  for(var x = 0; x< m.length;x++){
    p[x]=0;
    for(var y = 0; y<input.length;y++){
      if(input[y]==m[x]){
      p[x]++; 
 }}}
 for(var x = 0;x< p.length;x++){
   if(p[x] ==(Math.max.apply(null, p))){
     mode.push(m[x]);
 }} 
$("#output").text(mode);}
Harris Mowbray
fonte
0

Aqui está o meu caminho. Tento agrupar o punho de dados.

const _ = require("underscore")

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

O groupResult deve ser

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

Em seguida, encontre a propriedade que tem a maior matriz

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

O código completo parece

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;
}
Andy Lai
fonte
0
var cats = ['Tom','Fluffy','Tom','Bella','Chloe','Tom','Chloe'];
var counts = {};
var compare = 0;
var mostFrequent;
(function(array){
   for(var i = 0, len = array.length; i < len; i++){
       var word = array[i];

       if(counts[word] === undefined){
           counts[word] = 1;
       }else{
           counts[word] = counts[word] + 1;
       }
       if(counts[word] > compare){
             compare = counts[word];
             mostFrequent = cats[i];
       }
    }
  return mostFrequent;
})(cats);
Rubin Bhandari
fonte
0

Com ES6, você pode encadear o método assim:

    function findMostFrequent(arr) {
      return arr
        .reduce((acc, cur, ind, arr) => {
          if (arr.indexOf(cur) === ind) {
            return [...acc, [cur, 1]];
          } else {
            acc[acc.indexOf(acc.find(e => e[0] === cur))] = [
              cur,
              acc[acc.indexOf(acc.find(e => e[0] === cur))][1] + 1
            ];
            return acc;
          }
        }, [])
        .sort((a, b) => b[1] - a[1])
        .filter((cur, ind, arr) => cur[1] === arr[0][1])
        .map(cur => cur[0]);
    }
    
    console.log(findMostFrequent(['pear', 'apple', 'orange', 'apple']));
    console.log(findMostFrequent(['pear', 'apple', 'orange', 'apple', 'pear']));

Se dois elementos tiverem a mesma ocorrência, ele retornará os dois. E funciona com qualquer tipo de elemento.

Cuong Vu
fonte
você não deve usar a variável arrdentro de um escopo onde essa variável já está definida como um parâmetro. Isso pode levar a bugs dependendo do navegador usado.
mesqueeb
Qual arré referido por arr.indexOf(cur)? O parâmetro superior ou o que está dentro de reduzir ??
mesqueeb