Ottieni l'elemento con la più alta occorrenza in un array


87

Sto cercando un modo elegante per determinare quale elemento ha la più alta occorrenza ( modalità ) in un array JavaScript.

Ad esempio, in

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

l' 'apple'elemento è il più frequente.


Potresti adattare alcune idee da questa domanda Stackoverflow. stackoverflow.com/questions/840781/…
Nosredna,

Non ho letto le soluzioni troppo da vicino, ma qualcuna di esse incorpora la seguente sfumatura (ottimizzazione?), Basata sul requisito semplicemente di determinare quale elemento ha il maggior numero di occorrenze, piuttosto che quante occorrenze sono la maggior parte ... e quella sfumatura è che, poiché la matrice viene ripetuta, il conteggio può interrompersi quando la differenza tra le occorrenze più alte e le seconde più alte, è inferiore al numero di elementi rimasti per il ciclo, il ciclo può cessare, l'attuale più alto sarà il più alto
Dexygen

1
Anche queste soluzioni non sembrano tenere conto dei legami.
Dexygen

1
Nel caso in cui si sta cercando un'altra soluzione (che è un po 'più piccolo) stackoverflow.com/questions/40410470/...
daanvanham

Risposte:


95

Questa è solo la modalità. Ecco una soluzione rapida e non ottimizzata . Dovrebbe essere 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;
}

1
Bello ... ma funziona solo per le stringhe, non necessariamente una limitazione ma qualcosa da considerare.
James

Molte grazie, non mi aspettavo una soluzione completa. Funziona sia su corde che su numeri con un solo passaggio, il che è abbastanza carino.
morsa il

1
Ho aggiunto una versione di questo algoritmo per gestire i pareggi.
samandmoore

3
Ho dovuto sostituire `f (modeMap [el] == null) con if (! ModeMap [el]) perché mi stava facendo uno strano numero quando passavo [2, 3, 3] perché modeMap [el] era undefined non null.
Naz

1
Penso che sia ragionevole avere un tie-break, che in questo caso è l'elemento che viene prima nell'array. Ma potresti facilmente modificare questo algoritmo per darti il ​​massimo.
Wylliam Judd

63

Ci sono stati alcuni sviluppi in javascript dal 2009 - ho pensato di aggiungere un'altra opzione. Sono meno preoccupato dell'efficienza fino a quando non è effettivamente un problema, quindi la mia definizione di codice "elegante" (come stipulato dall'OP) favorisce la leggibilità - che è ovviamente soggettiva ...

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

In questo particolare esempio, se due o più elementi dell'insieme hanno occorrenze uguali, verrà restituito quello che appare per ultimo nell'array. Vale anche la pena sottolineare che modificherà il tuo array originale, cosa che può essere prevenuta se lo desideri con una Array.slicechiamata in anticipo.


Modifica: aggiornato l'esempio con alcune frecce grasse ES6 perché è successo il 2015 e penso che siano carine ... Se sei preoccupato per la retrocompatibilità, puoi trovarlo nella cronologia delle revisioni .


È fantastico! Ora come restituireste più risposte se c'è più di un elemento nell'array che si presenta allo stesso modo di un altro?
Crystal

È ingenuo in quanto presume che la modalità sia unica, se richiedi che ne restituisca più di uno, devi tenere traccia del conteggio totale per ogni oggetto che non sembra così carino ... potresti provare qualcosa del genere , è semplicistico in quanto funzionerà solo con valori primitivi (ma è possibile adattarlo ulteriormente se necessario).
Emissario

15
Se questo non è un codice elegante, non so cosa sia. È come una pubblicità per la programmazione funzionale.
Sam H.

1
@GoranJakovljevic Puoi essere più specifico? Immagino siano le funzioni freccia ES6 : hai provato l' esempio compatibile con le versioni precedenti nella cronologia delle revisioni?
Emissario

Hai ragione, le sue funzioni di freccia. Sì, al contrario funziona bene.
Goran Jakovljevic

38

Come da George Jempty'srichiesta per tenere conto dei legami dell'algoritmo, propongo una versione modificata Matthew Flaschen'sdell'algoritmo.

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

Questo ora restituirà una stringa con gli elementi mode delimitati da un &simbolo. Quando il risultato viene ricevuto, può essere suddiviso su &quell'elemento e hai le tue modalità.

Un'altra opzione sarebbe quella di restituire un array di elementi mode in questo modo:

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

Nell'esempio precedente saresti quindi in grado di gestire il risultato della funzione come un array di modalità.


1
Nel secondo esempio (quello dell'array); non è necessario impostare modesa [array[0]]come valore iniziale. Questo ti assicurerà di avere duplicati in modes. Questo dovrebbe fare il truccovar modes = []
vdclouis

1
È fantastico! Tuttavia, quando provo questo con un array con due valori diversi, restituisce due volte il primo elemento dell'array. Non so perché sta succedendo ...
Crystal

@xgrioux apporta la modifica consigliata da vdclouis per contrastare questo bug. cioè cambia [array [0]] in [].
Dave Haigh,

consiglia di modificare le istanze di ==a ===per applicare una rigorosa uguaglianza
Len Joseph,

16

Sulla base della risposta ES6 + di Emissary , potresti usare Array.prototype.reduceper fare il tuo confronto (al contrario di ordinare, scoppiare e potenzialmente mutare il tuo array), che penso sia abbastanza fluido.

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

L'impostazione predefinita è null, che non ti darà sempre una risposta veritiera se null è una possibile opzione per cui stai filtrando, forse potrebbe essere un secondo argomento opzionale

Lo svantaggio, come con varie altre soluzioni, è che non gestisce gli "stati di estrazione", ma ciò potrebbe comunque essere ottenuto con una funzione di riduzione leggermente più coinvolta.


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

Questo è ancora O (n), ma utilizza inutilmente due passaggi.
Matthew Flaschen

2
Poiché viene trasmesso JavaScript, è sempre interessante vedere piccole soluzioni.
Nosredna

Lol 2 meno per una soluzione adeguata;] Ho corretto due passaggi inutilmente, lo stavo rendendo veloce, ma funziona ancora ed è ancora la soluzione più breve.
Pensatore

ogni accesso a b richiede almeno log (len (b)) quindi O (n) potrebbe essere un po 'ottimista
Nicolas78

nicolas78: Se l'array è piccolo, non importa. Quindi dipende dal tuo progetto.
Pensatore

7

Poiché utilizzo questa funzione come quiz per gli intervistatori, pubblico la mia soluzione:

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))

6

Provare un approccio dichiarativo qui. Questa soluzione crea un oggetto per calcolare le occorrenze di ogni parola. Quindi filtra l'oggetto in un array confrontando le occorrenze totali di ogni parola con il valore più alto trovato nell'oggetto.

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

Spiega la tua risposta per favore
Haris

Eviterei di calcolare il massimo nel ciclo del filtro e rimuoverei l'istruzione della mappa chiavi-valori. Anche se questa risposta non è la più performante, non è così male come il filtraggio nel riduttore ed è piacevole e leggibile. const maxValue = Math.max (... Object.values ​​(totals)); const risultati = keys.filter (x => totali [x] === maxValue);
milesaron

3

Tempo per un'altra soluzione:

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 la brevità è importante (non lo è), allora:

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 si devono evitare membri inesistenti (ad es. Array sparse), è richiesto un test hasOwnProperty aggiuntivo :

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

Altre risposte qui torneranno indefinite .


@ Jonah: la brevità, fine a se stessa, è inutile e di solito rende il codice più difficile da leggere e mantenere. Ovviamente un codice più dettagliato non è necessariamente migliore solo per essere più lungo. Ma questi criteri, di per sé, sono ovviati da misure molto più importanti come la chiarezza e la manutenibilità.
RobG

Ovviamente l'obiettivo non è mai una concisione densa e criptica. Ma in generale, date due versioni dello stesso codice con densità più o meno uguale, quella più corta è solitamente più chiara e migliore. Non sto dicendo che sia una regola , ma la correlazione è forte. In effetti, direi che non esiste un altro singolo indicatore così altamente correlato alla leggibilità. È per questo che ogni programmatore ama eliminare il codice. È per questo che la maggior parte delle riscritture in Code Review sono più brevi dell'originale.
Jonah

3

Un'altra soluzione JS da: https://www.w3resource.com/javascript-exercises/javascript-array-exercise-8.php

Puoi provare anche questo:

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

3

Ecco un altro modo di ES6 per farlo con complessità 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);

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
}

Il problema con questa soluzione è che le parole "max" e "mode" non contano perché fanno parte della logica nella mappa ...
Pablo

2

Ecco la mia soluzione a questo problema, ma con i numeri e utilizzando la nuova funzione "Imposta". Non è molto performante ma mi sono decisamente divertito a scriverlo e supporta più valori massimi.

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 proposito, non usarlo per la produzione, questa è solo un'illustrazione di come puoi risolverlo solo con le funzioni ES6 e Array.


2

Ecco la mia soluzione: -

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


2

Per il bene di un codice davvero facile da leggere e gestibile, condivido questo:

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

Spero che aiuti qualcuno;)!


2

Questa soluzione può restituire più elementi di un array in caso di parità. Ad esempio, un array

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

ha due valori di modalità: 3e 6.

Ecco la soluzione.

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

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

Nota: ct è la lunghezza dell'array.

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

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

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

1

Provalo anche tu, questo non tiene conto della versione del browser.

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

Notare che questa funzione restituisce l'ultima occorrenza nell'array quando 2 o più voci compaiono lo stesso numero di volte!


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

1

Ecco la versione moderna che utilizza mappe integrate (quindi funziona su più cose che possono essere convertite in stringhe uniche):

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


0

Immagino che tu abbia due approcci. Entrambi hanno vantaggi.

Ordina quindi Count o Loop through e usa una tabella hash per fare il conteggio per te.

La tabella hash è carina perché una volta terminata l'elaborazione hai anche tutti gli elementi distinti. Se avessi milioni di elementi, però, la tabella hash potrebbe finire per utilizzare molta memoria se il tasso di duplicazione è basso. L'approccio sort, then count avrebbe un'impronta di memoria molto più controllabile.


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

0

Puoi provare questo:

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

0

Potresti risolverlo in O (n) complessità

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 copiare e incollare nella console Chrome per eseguire il codice sopra.


0

Questa funzione è una funzione generica per ogni tipo di informazione. Conta l'occorrenza degli elementi e quindi restituisce l'array con il numero massimo di elementi che si verificano.

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

0

Ecco la mia strada. Cerco di raggruppare i dati pugno.

const _ = require("underscore")

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

Il groupResult dovrebbe essere

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

Quindi trova la proprietà che ha l'array più lungo

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

Il codice completo sembra

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

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

0

Con ES6, puoi concatenare il metodo in questo modo:

    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 due elementi hanno la stessa occorrenza, verranno restituiti entrambi. E funziona con qualsiasi tipo di elemento.


non dovresti usare la variabile arrall'interno di uno scope dove quella variabile è già definita come parametro. Ciò può portare a bug a seconda del browser utilizzato.
mesqueeb

A cosa arrsi riferisce arr.indexOf(cur)? Il parametro in alto, o quello all'interno della riduzione ??
mesqueeb
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.