Ruft das Element mit dem höchsten Vorkommen in einem Array ab


82

Ich suche nach einer eleganten Methode, um festzustellen, welches Element in einem JavaScript-Array am häufigsten vorkommt ( Modus ).

Zum Beispiel in

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

Das 'apple'Element ist das häufigste.


Sie können einige Ideen aus dieser Stackoverflow-Frage anpassen. stackoverflow.com/questions/840781/…
Nosredna

Ich habe die Lösungen nicht zu genau gelesen, aber enthält eine von ihnen die folgende Nuance (Optimierung?), Basierend auf der Anforderung, lediglich zu bestimmen, welches Element am häufigsten vorkommt und nicht wie viele Vorkommen am häufigsten vorkommen .... und diese Nuance ist, dass, wenn das Array durchlaufen wird, das Zählen aufhören kann, wenn die Differenz zwischen dem höchsten und dem zweithöchsten Vorkommen geringer ist als die Anzahl der Elemente, die noch durchlaufen werden müssen. Das Schleifen kann aufhören, das aktuell höchste ist das höchste
Dexygen

1
Auch diese Lösungen scheinen keine Bindungen zu erklären.
Dexygen

1
Für den Fall, dass Sie nach einer anderen Lösung suchen (die etwas kleiner ist) stackoverflow.com/questions/40410470/…
daanvanham

Antworten:


90

Dies ist nur der Modus. Hier ist eine schnelle, nicht optimierte Lösung. Es sollte O (n) sein.

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
Schön ... aber es funktioniert nur für Strings - nicht unbedingt eine Einschränkung, aber etwas zu beachten.
James

Vielen Dank, ich hatte keine vollständige Lösung erwartet. Funktioniert sowohl mit Zeichenfolgen als auch mit Zahlen mit nur einem Durchgang, was sehr schön ist.
Schraubstock

1
Ich habe eine Version dieses Algorithmus hinzugefügt, um Krawatten zu handhaben.
Samandmoore

3
Ich musste `f (modeMap [el] == null) durch if (! ModeMap [el]) ersetzen, da es mir beim Übergeben von [2, 3, 3] eine seltsame Zahl gab, weil modeMap [el] undefiniert und nicht null war.
Naz

1
Ich denke, es ist vernünftig, einen Tie-Breaker zu haben, der in diesem Fall das Element ist, das im Array an erster Stelle steht. Sie können diesen Algorithmus jedoch leicht ändern, um die meisten für die meisten zu erhalten.
Wylliam Judd

58

Seit 2009 gibt es einige Entwicklungen in Javascript - ich dachte, ich würde eine weitere Option hinzufügen. Ich bin weniger mit Effizienz beschäftigt, bis es tatsächlich ein Problem ist, daher begünstigt meine Definition von "elegantem" Code (wie vom OP festgelegt) die Lesbarkeit - was natürlich subjektiv ist ...

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

Wenn in diesem speziellen Beispiel zwei oder mehr Elemente der Menge gleich vorkommen, wird dasjenige zurückgegeben, das zuletzt im Array angezeigt wird. Es ist auch erwähnenswert, dass dadurch Ihr ursprüngliches Array geändert wird - was verhindert werden kann, wenn Sie dies Array.slicevorher mit einem Aufruf wünschen .


Edit: das Beispiel mit einigen aktualisiert ES6 Fett Pfeile , weil 2015 passiert ist, und ich denke , sie sehen ziemlich ... Wenn Sie mit der Abwärtskompatibilität betroffen sind können Sie dies finden in der Revisionshistorie .


Das ist toll! Wie würden Sie nun mehrere Antworten zurückgeben, wenn mehr als ein Element im Array vorhanden ist, das genauso vorkommt wie ein anderes?
Crystal

Es ist insofern naiv, als davon ausgegangen wird, dass der Modus eindeutig ist. Wenn Sie mehr als einen Modus zurückgeben möchten, müssen Sie die Gesamtzahl für jedes Element verfolgen, das nicht so hübsch aussieht. Sie können so etwas ausprobieren Es ist einfach, da es nur mit primitiven Werten funktioniert (aber Sie können es bei Bedarf weiter anpassen).
Abgesandter

13
Wenn dies kein eleganter Code ist, weiß ich nicht, was es ist. Es ist wie eine Werbung für funktionale Programmierung.
Sam H.

1
@GoranJakovljevic Kannst du genauer sein? Ich würde mir vorstellen, dass es sich um die ES6-Pfeilfunktionen handelt. Haben Sie das abwärtskompatible Beispiel in der Revisionshistorie ausprobiert ?
Abgesandter

Sie sind richtig, seine Pfeilfunktionen. Ja, rückwärts funktioniert gut.
Goran Jakovljevic

36

Auf George Jempty'sAnfrage, dass der Algorithmus Bindungen berücksichtigt, schlage ich eine modifizierte Version des Matthew Flaschen'sAlgorithmus vor.

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

Dies gibt nun eine Zeichenfolge mit den durch ein &Symbol begrenzten Moduselementen zurück. Wenn das Ergebnis empfangen wird, kann es auf dieses &Element aufgeteilt werden und Sie haben Ihre Modi.

Eine andere Möglichkeit wäre, ein Array von Moduselementen wie folgt zurückzugeben:

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

Im obigen Beispiel könnten Sie dann das Ergebnis der Funktion als Array von Modi behandeln.


1
Im zweiten Beispiel (dem Array eins); Sie nicht festlegen müssen , modesum [array[0]]als Anfangswert. Dadurch wird sichergestellt, dass Sie Duplikate haben modes. Dies sollte den Trick tunvar modes = []
vdclouis

1
Das ist toll! Wenn ich dies jedoch mit einem Array mit zwei verschiedenen Werten teste, wird das erste Element im Array zweimal zurückgegeben. Ich bin mir nicht sicher, warum das passiert ...
Crystal

@xgrioux nimmt die Änderung vor, die vdclouis empfiehlt, um diesem Fehler entgegenzuwirken. dh ändere [Array [0]] auf [].
Dave Haigh

empfehlen, Instanzen von ==zu ändern ===, um strikte Gleichheit durchzusetzen
Len Joseph

15

Basierend auf der ES6 + -Antwort von Emissary könnten Array.prototype.reduceSie Ihren Vergleich durchführen (im Gegensatz zum Sortieren, Poppen und potenziellen Mutieren Ihres Arrays), was meiner Meinung nach ziemlich schick aussieht.

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

Ich verwende standardmäßig null, was Ihnen nicht immer eine wahrheitsgemäße Antwort gibt, wenn null eine mögliche Option ist, nach der Sie filtern. Vielleicht könnte dies ein optionales zweites Argument sein

Der Nachteil ist, wie bei verschiedenen anderen Lösungen, dass es keine "Zeichnungszustände" behandelt, aber dies könnte immer noch mit einer etwas komplizierteren Reduktionsfunktion erreicht werden.


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

Dies ist immer noch O (n), es werden jedoch unnötigerweise zwei Durchgänge verwendet.
Matthew Flaschen

2
Da JavaScript übertragen wird, ist es immer interessant, kleine Lösungen zu sehen.
Nosredna

Lol 2 minus für die richtige Lösung;] Ich habe unnötigerweise zwei Durchgänge korrigiert, habe es schnell gemacht, aber es funktioniert immer noch und ist immer noch die kürzeste Lösung.
Denker

Jeder Zugriff auf b benötigt mindestens log (len (b)), sodass O (n) möglicherweise etwas optimistisch ist
Nicolas78

nicolas78: Wenn das Array klein ist, spielt es keine Rolle. Das hängt also von Ihrem Projekt ab.
Denker

5

Hier einen deklarativen Ansatz ausprobieren. Diese Lösung erstellt ein Objekt, um die Vorkommen jedes Wortes zu erfassen. Anschließend wird das Objekt auf ein Array heruntergefiltert, indem die Gesamtvorkommen jedes Wortes mit dem höchsten im Objekt gefundenen Wert verglichen werden.

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

Erklären Sie bitte Ihre Antwort
Haris

Ich würde es vermeiden, das Maximum in der Filterschleife zu berechnen, und die Map-Anweisung "Schlüssel zu Werten" entfernen. Diese Antwort ist zwar nicht die performanteste, aber nicht so schlecht wie das Filtern im Reduzierer und imho nett und lesbar. const maxValue = Math.max (... Object.values ​​(Summen)); const results = keys.filter (x => totals [x] === maxValue);
Milesaron

4

Da ich diese Funktion als Quiz für die Interviewer verwende, poste ich meine Lösung:

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

3

Eine weitere JS-Lösung von: https://www.w3resource.com/javascript-exercises/javascript-array-exercise-8.php

Kann das auch versuchen:

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

Hier ist eine andere ES6-Methode mit O (n) -Komplexität

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

Zeit für eine andere Lösung:

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

Wenn es auf die Kürze ankommt (nicht), dann:

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

Wenn nicht vorhandene Mitglieder vermieden werden sollen (z. B. spärliches Array), ist ein zusätzlicher hasOwnProperty- Test erforderlich:

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

Andere Antworten hier werden undefiniert zurückgegeben .


@ Jonah - Kürze ist um ihrer selbst willen sinnlos und erschwert normalerweise das Lesen und Verwalten von Code. Natürlich ist ausführlicherer Code nicht unbedingt besser, nur um länger zu sein. Diese Kriterien selbst werden jedoch durch viel wichtigere Maßnahmen wie Klarheit und Wartbarkeit vermieden.
RobG

Offensichtlich ist dichte, kryptische Kürze niemals das Ziel. Bei zwei Versionen desselben Codes mit ungefähr gleicher Dichte ist die kürzere Version im Allgemeinen klarer und besser. Ich sage nicht, dass es eine Regel ist , aber die Korrelation ist stark. Tatsächlich würde ich sagen, dass es keinen anderen Einzelindikator gibt , der so stark mit der Lesbarkeit korreliert. Deshalb liebt es jeder Programmierer, Code zu löschen. Aus diesem Grund sind die meisten Umschreibungen in Code Review kürzer als das Original.
Jonah

2

Diese Lösung kann mehrere Elemente eines Arrays zurückgeben, wenn sie gleichzeitig auftreten. Beispielsweise hat ein Array arr = [3,4,3,6,4] zwei Moduswerte, 3 und 6.

Hier ist die Lösung,

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

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
}

Das Problem mit dieser Lösung ist, dass die Wörter "max" und "mode" nicht als Teil der Logik in der Karte zählen ...
Pablo

2

Hier ist meine Lösung für dieses Problem, aber mit Zahlen und unter Verwendung der neuen 'Set'-Funktion. Es ist nicht sehr performant, aber ich hatte definitiv viel Spaß beim Schreiben und es unterstützt mehrere Maximalwerte.

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]

Verwenden Sie dies übrigens nicht für die Produktion. Dies ist nur ein Beispiel dafür, wie Sie es nur mit ES6- und Array-Funktionen lösen können.


2

Hier ist meine Lösung: -

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


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

Hinweis: ct ist die Länge des Arrays.

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

Versuchen Sie es auch, dies berücksichtigt nicht die Browserversion.

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

Bitte beachten Sie, dass diese Funktion das letzte Vorkommen im Array zurückgibt, wenn zwei oder mehr Einträge gleich oft erscheinen!


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

Hier ist die moderne Version mit integrierten Karten (sie funktioniert also nicht nur mit Dingen, die in eindeutige Zeichenfolgen konvertiert werden können):

'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

Ich denke, Sie haben zwei Ansätze. Beides hat Vorteile.

Sortieren Sie dann Count oder Loop Through und verwenden Sie eine Hash-Tabelle, um die Zählung für Sie durchzuführen.

Die Hashtabelle ist schön, denn wenn Sie mit der Verarbeitung fertig sind, haben Sie auch alle unterschiedlichen Elemente. Wenn Sie jedoch Millionen von Elementen hatten, könnte die Hash-Tabelle viel Speicherplatz beanspruchen, wenn die Duplizierungsrate niedrig ist. Der Ansatz "Sortieren, dann Zählen" hätte einen viel besser kontrollierbaren Speicherbedarf.


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

Sie können dies versuchen:

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

Sie könnten es in O (n) Komplexität lösen

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

Kopieren Sie einfach die Chrome-Konsole und fügen Sie sie ein, um den obigen Code auszuführen.


0

Diese Funktion ist eine generische Funktion für jede Art von Informationen. Es zählt das Auftreten der Elemente und gibt dann ein Array mit maximal auftretenden Elementen zurück.

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

Hier ist mein Weg. Ich versuche, Datenfaust zu gruppieren.

const _ = require("underscore")

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

Das groupResult sollte sein

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

Suchen Sie dann die Eigenschaft mit dem längsten Array

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

Der vollständige Code sieht aus wie

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

Mit ES6 können Sie die Methode folgendermaßen verketten:

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

Wenn zwei Elemente dasselbe Vorkommen haben, werden beide zurückgegeben. Und es funktioniert mit jeder Art von Element.


Sie sollten die Variable nicht arrin einem Bereich verwenden, in dem diese Variable bereits als Parameter definiert ist. Dies kann je nach verwendetem Browser zu Fehlern führen.
Mesqueeb

Auf welche arrbezieht sich arr.indexOf(cur)? Der oberste Parameter oder der innerhalb des Reduzierens?
Mesqueeb

0

Um einen wirklich einfach zu lesenden, wartbaren Code zu erhalten, teile ich Folgendes:

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

Hoffe es hilft jemandem;)!

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.