Obtenga el elemento con la mayor incidencia en una matriz

85

Estoy buscando una forma elegante de determinar qué elemento tiene la mayor incidencia ( modo ) en una matriz de JavaScript.

Por ejemplo, en

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

el 'apple'elemento es el más frecuente.

tornillo
fuente
Podría adaptar algunas ideas de esta pregunta de Stackoverflow. stackoverflow.com/questions/840781/…
Nosredna
No he leído las soluciones con demasiada atención, pero ¿alguna de ellas incorpora el siguiente matiz (¿optimización?), Basado en el requisito simplemente para determinar qué elemento tiene la mayor cantidad de ocurrencias, en lugar de cuántas ocurrencias es la mayor ... y ese matiz es que, a medida que se repite la matriz, el conteo puede detenerse cuando la diferencia entre las ocurrencias más altas y las segundas más altas es menor que el número de elementos que quedan por recorrer, el bucle puede cesar, la corriente más alta será la más alta
Dexygen
1
Además, estas soluciones no parecen tener en cuenta los vínculos.
Dexygen
1
En caso de que esté buscando otra solución (que sea un poco más pequeña) stackoverflow.com/questions/40410470/…
daanvanham

Respuestas:

94

Este es solo el modo. Aquí tienes una solución rápida y no optimizada . Debería 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
fuente
1
Agradable ... pero solo funciona para cadenas, no necesariamente una limitación, sino algo a considerar.
James
Muchas gracias, no esperaba una solución completa. Funciona tanto en cadenas como en números con una sola pasada, lo cual es bastante bueno.
tornillo de banco
1
Agregué una versión de este algoritmo para manejar vínculos.
Samandmoore
3
Tuve que reemplazar `f (modeMap [el] == null) con if (! ModeMap [el]) ya que me estaba sumergiendo en un número extraño al pasar [2, 3, 3] porque modeMap [el] no estaba definido y no era nulo.
Naz el
1
Creo que es razonable tener un desempate, que en este caso es el elemento que viene primero en la matriz. Pero podría modificar fácilmente este algoritmo para que cada uno empate en la mayoría.
Wylliam Judd
62

Ha habido algunos desarrollos en javascript desde 2009; pensé en agregar otra opción. Me preocupa menos la eficiencia hasta que en realidad es un problema, por lo que mi definición de código "elegante" (según lo estipulado por el OP) favorece la legibilidad, que por supuesto es subjetiva ...

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

En este ejemplo particular, si dos o más elementos del conjunto tienen ocurrencias iguales, se devolverá el que aparece más tarde en la matriz. También vale la pena señalar que modificará su matriz original, lo que puede evitarse si lo desea con una Array.slicellamada de antemano.


Editar: actualicé el ejemplo con algunas flechas gordas de ES6 porque sucedió 2015 y creo que se ven bonitas ... Si le preocupa la compatibilidad con versiones anteriores, puede encontrar esto en el historial de revisiones .

Emisario
fuente
¡Esto es genial! Ahora, ¿cómo devolvería varias respuestas si hay más de un elemento en la matriz que ocurre igual que otro?
Crystal
Es ingenuo ya que asume que el modo es único, si necesita que devuelva más de uno, entonces necesita llevar un registro del recuento total de cada elemento que no se ve tan bonito ... podría intentar algo como esto , es simplista porque solo funcionará con valores primitivos (pero puede adaptarlo más si es necesario).
Emisario
14
Si este no es un código elegante, no sé qué es. Es como un anuncio de programación funcional.
Sam H.
1
@GoranJakovljevic ¿Puede ser más específico? Me imagino que son las funciones de flecha de ES6 : ¿ha probado el ejemplo compatible con versiones anteriores en el historial de revisiones?
Emisario
Tienes razón, su flecha funciona. Sí, al revés funciona bien.
Goran Jakovljevic
37

Según la George Jempty'ssolicitud para que el algoritmo tenga en cuenta los vínculos, propongo una versión modificada del 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;
}

Esto devolverá ahora una cadena con los elementos de modo delimitados por un &símbolo. Cuando se recibe el resultado, se puede dividir en ese &elemento y tiene su (s) modo (s).

Otra opción sería devolver una matriz de elemento (s) de modo así:

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

En el ejemplo anterior, podría manejar el resultado de la función como una matriz de modos.

Samandmoore
fuente
1
En el segundo ejemplo (el de matriz); usted no necesita fijar modesa [array[0]]como valor inicial. Esto asegurará que tengas duplicados en formato modes. Esto debería funcionarvar modes = []
vdclouis
1
¡Esto es genial! Sin embargo, cuando pruebo esto con una matriz con dos valores diferentes, devuelve el primer elemento de la matriz dos veces. No estoy seguro de por qué está pasando eso ...
Crystal
@xgrioux realiza el cambio que vdclouis recomienda para contrarrestar este error. es decir, cambie [matriz [0]] a [].
Dave Haigh
recomendar cambiar instancias de ==to ===para hacer cumplir la igualdad estricta
Len Joseph
16

Basado en la respuesta ES6 + de Emissary , podría usar Array.prototype.reducepara hacer su comparación (en lugar de ordenar, hacer estallar y potencialmente mutar su matriz), que creo que parece bastante hábil.

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

El valor predeterminado es nulo, que no siempre le dará una respuesta veraz si nulo es una opción posible por la que está filtrando, tal vez ese podría ser un segundo argumento opcional

La desventaja, al igual que con otras soluciones, es que no maneja los 'estados de dibujo', pero esto aún podría lograrse con una función de reducción un poco más complicada.

Davidsharp
fuente
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
fuente
Esto sigue siendo O (n), pero usa innecesariamente dos pasadas.
Matthew Flaschen
2
Dado que JavaScript se transmite, siempre es interesante ver pequeñas soluciones.
Nosredna
Lol 2 menos para la solución adecuada;] Corregí innecesariamente dos pasadas, lo estaba haciendo rápido, pero aún funciona y sigue siendo la solución más corta.
Pensador
cada acceso a b requiere al menos log (len (b)) por lo que O (n) podría ser un poco optimista
Nicolas78
nicolas78: Si la matriz es pequeña, no importa. Entonces depende de tu proyecto.
Pensador
7

Como estoy usando esta función como un cuestionario para los entrevistadores, publico mi solución:

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
fuente
5

Probando un enfoque declarativo aquí. Esta solución crea un objeto para contar las ocurrencias de cada palabra. Luego filtra el objeto a una matriz comparando el total de apariciones de cada palabra con el valor más alto encontrado en el 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
fuente
Explique su respuesta por favor
Haris
Evitaría calcular el máximo en el ciclo de filtro y eliminaría la declaración del mapa de claves a valores. Si bien esta respuesta no es la más eficaz, no es tan mala como filtrar en el reductor y es agradable y legible en mi humilde opinión. const maxValue = Math.max (... Object.values ​​(totales)); resultados const = keys.filter (x => totales [x] === maxValue);
milesaron
3

Es hora de otra solución:

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

Si la brevedad importa (no es así), entonces:

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

Si se deben evitar miembros inexistentes (por ejemplo, matriz dispersa), se requiere una prueba adicional de hasOwnProperty :

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

Otras respuestas aquí aparecerán indefinidas .

RobG
fuente
@ Jonah: la brevedad, por sí misma, no tiene sentido y normalmente hace que el código sea más difícil de leer y mantener. Por supuesto, un código más detallado no es necesariamente mejor solo por ser más largo. Pero esos criterios, por sí mismos, son obviados por medidas mucho más importantes como la claridad y la facilidad de mantenimiento.
RobG
Obviamente, la brevedad densa y críptica nunca es el objetivo. Pero, en general, dadas dos versiones del mismo código con aproximadamente la misma densidad, la más corta suele ser más clara y mejor. No digo que sea una regla , pero la correlación es fuerte. De hecho, yo diría que no hay otro único indicador tan altamente correlacionado con la legibilidad. Es por eso que a todos los programadores les encanta eliminar códigos. Es por eso que la mayoría de las reescrituras en Code Review son más breves que el original.
Jonás
3

Otra solución JS de: https://www.w3resource.com/javascript-exercises/javascript-array-exercise-8.php

Puede probar esto también:

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
fuente
3

Aquí hay otra forma de ES6 de hacerlo con complejidad 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
fuente
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
}
Jonás
fuente
El problema con esta solución es que las palabras "max" y "mode" no cuentan, ya que son parte de la lógica en el mapa ...
Pablo
2

Aquí está mi solución a este problema, pero con números y usando la nueva función 'Establecer'. No es muy eficaz, pero definitivamente me divertí mucho escribiendo esto y admite múltiples 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]

Por cierto, no use esto para producción, esto es solo una ilustración de cómo puede resolverlo solo con las funciones ES6 y Array.

Anjuna5
fuente
2

Aquí está mi solución: -

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
fuente
2

En aras de un código realmente fácil de leer y mantenible, comparto esto:

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 ayude a alguien;)!

Eliecer Chicott
fuente
2

Esta solución puede devolver varios elementos de una matriz en caso de empate. Por ejemplo, una matriz

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

tiene dos valores de modo: 3y 6.

Aqui esta la solucion.

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
fuente
1
var mode = 0;
var c = 0;
var num = new Array();
var value = 0;
var greatest = 0;
var ct = 0;

Nota: ct es la longitud de la 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
fuente
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
fuente
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
fuente
1

Pruébelo también, esto no tiene en cuenta la versión del 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']));

Tenga en cuenta que esta función devuelve la última aparición en la matriz cuando aparecen 2 o más entradas el mismo número de veces.

Marcelo
fuente
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
fuente
1

Aquí está la versión moderna que usa mapas integrados (por lo que funciona en más cosas que se pueden convertir en cadenas únicas):

'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-
fuente
0

Supongo que tienes dos enfoques. Ambos tienen ventajas.

Ordene y luego cuente o recorra en bucle y use una tabla hash para hacer el conteo por usted.

La tabla hash es buena porque una vez que haya terminado de procesar, también tendrá todos los elementos distintos. Sin embargo, si tuviera millones de elementos, la tabla hash podría terminar usando mucha memoria si la tasa de duplicación es baja. El método de ordenar y luego contar tendría una huella de memoria mucho más controlable.

Steve Sheldon
fuente
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
fuente
0

Puedes probar esto:

 // 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
fuente
0

Podrías resolverlo en complejidad 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" );

Simplemente copie y pegue en la consola de Chrome para ejecutar el código anterior.

Sandeep Gantait
fuente
0

Esta función es una función genérica para todo tipo de información. Cuenta la ocurrencia de los elementos y luego devuelve una matriz con el máximo de elementos que ocurren.

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;
}
רונן ברברמן
fuente
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
fuente
0

Este es mi camino. Intento agrupar datos de puño.

const _ = require("underscore")

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

El groupResult debe ser

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

Luego encuentra la propiedad que tiene la matriz más larga

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

El 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
fuente
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
fuente
0

Con ES6, puede encadenar el método de esta manera:

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

Si dos elementos tienen la misma ocurrencia, devolverá ambos. Y funciona con cualquier tipo de elemento.

Cuong Vu
fuente
no debe usar la variable arrdentro de un ámbito donde esa variable ya está definida como parámetro. Esto puede provocar errores según el navegador que se utilice.
mesqueeb
¿A cuál arrse refiere arr.indexOf(cur)? ¿El parámetro superior, o el que está dentro de reducir?
mesqueeb