Получить элемент с наибольшим вхождением в массив


87

Я ищу элегантный способ определить, какой элемент имеет наибольшее вхождение ( режим ) в массиве JavaScript.

Например, в

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

'apple'элемент является наиболее частой один.


Вы можете адаптировать некоторые идеи из этого вопроса о Stackoverflow. stackoverflow.com/questions/840781/…
Nosredna

Я не слишком внимательно читал решения, но включает ли какое-либо из них следующий нюанс (оптимизация?), Основанный на требовании просто определить, какой элемент имеет больше всего вхождений, а не сколько вхождений больше всего .... и этот нюанс заключается в том, что по мере зацикливания массива подсчет может остановиться, когда разница между наивысшим и вторым по величине вхождением меньше, чем количество элементов, оставшихся для цикла, цикл может прекратиться, текущий наивысший будет самым высоким
Dexygen

1
Также эти решения, похоже, не учитывают связи.
Dexygen

1
Если вы ищете другое решение (которое немного меньше) stackoverflow.com/questions/40410470/…
daanvanham

Ответы:


95

Это просто режим. Вот быстрое неоптимизированное решение. Это должно быть 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
Красиво ... но это работает только для строк - не обязательно ограничение, но то, что нужно учитывать.
Джеймс

Большое спасибо, я не ожидал полного решения. Работает как со строками, так и с числами всего за один проход, что довольно приятно.
vise

1
Я добавил версию этого алгоритма для обработки связей.
samandmoore

3
Мне пришлось заменить `f (modeMap [el] == null) на if (! ModeMap [el]), поскольку он подводил меня к странному номеру при передаче [2, 3, 3], потому что modeMap [el] был undefined not null.
Naz

1
Я думаю, что разумно иметь тай-брейк, который в данном случае является элементом, который идет первым в массиве. Но вы можете легко изменить этот алгоритм, чтобы у каждого из них было больше всего.
Уиллиам Джадд

63

С 2009 года в javascript произошли некоторые изменения - я подумал, что добавлю еще один вариант. Меня меньше беспокоит эффективность, пока это не станет проблемой, поэтому мое определение «элегантного» кода (как предусмотрено OP) способствует удобочитаемости - что, конечно, субъективно ...

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

В этом конкретном примере, если два или более элемента набора имеют одинаковые вхождения, будет возвращен тот, который появляется последним в массиве. Также стоит отметить, что он изменит ваш исходный массив, что можно предотвратить, если вы хотите, Array.sliceпредварительно позвонив.


Изменить: обновлен пример с некоторыми жирными стрелками ES6, потому что произошел 2015 год, и я думаю, что они выглядят красиво ... Если вас беспокоит обратная совместимость, вы можете найти это в истории изменений .


Это замечательно! Теперь, как бы вы вернули несколько ответов, если в массиве есть более одного элемента, который встречается так же, как другой?
Crystal

Это наивно в том смысле, что он предполагает, что режим уникален, если вам требуется, чтобы он возвращал более одного, вам нужно отслеживать общее количество для каждого элемента, который выглядит не так красиво ... вы можете попробовать что-то вроде этого , это упрощенно в том смысле, что он будет работать только с примитивными значениями (но при необходимости вы можете адаптировать его дальше).
Эмиссар

15
Если это не элегантный код, я не знаю, что это такое. Это как реклама функционального программирования.
Sam H.

1
@GoranJakovljevic Вы можете быть более конкретными? Я бы предположил, что это стрелочные функции ES6 - пробовали ли вы пример обратной совместимости в истории изменений?
Эмиссар

Вы правы, его стрелка работает. Да, перемотка работает нормально.
Горан Яковлевич

38

В соответствии с George Jempty'sпросьбой о том, чтобы алгоритм учитывал связи, я предлагаю модифицированный вариант Matthew Flaschen'sалгоритма.

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

Теперь будет возвращена строка с элементами режима, разделенными &символом. Когда результат получен, его можно разделить на этот &элемент, и у вас будет свой режим (ы).

Другой вариант - вернуть массив элементов режима, например:

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

В приведенном выше примере вы сможете обработать результат функции как массив режимов.


1
Во втором примере (массив один); вам не нужно устанавливать его modesв [array[0]]качестве начального значения. Это гарантирует, что у вас есть дубликаты modes. Это должно var modes = []
сработать

1
Это замечательно! Однако, когда я тестирую это с массивом с двумя разными значениями, он дважды возвращает первый элемент в массиве. Не уверен, почему это происходит ...
Кристалл

@xgrioux внесите изменение, которое vdclouis рекомендует для устранения этой ошибки. т.е. измените [array [0]] на [].
Дэйв Хэй,

рекомендую изменить экземпляры ==на, ===чтобы обеспечить строгое равенство
Лен Джозеф

16

Основываясь на ответе Emissary ES6 +, вы можете использовать его Array.prototype.reduceдля сравнения (в отличие от сортировки, извлечения и потенциального изменения вашего массива), что, на мой взгляд, выглядит довольно гладко.

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

По умолчанию я использую значение null, что не всегда дает вам правдивый ответ, если значение null - это возможный вариант, который вы фильтруете, возможно, это может быть необязательный второй аргумент

Обратной стороной, как и в случае с различными другими решениями, является то, что он не обрабатывает «состояния рисования», но этого все же можно достичь с помощью немного более сложной функции сокращения.


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

Это все еще O (n), но без необходимости используется два прохода.
Matthew Flaschen

2
Поскольку JavaScript передается, всегда интересно видеть небольшие решения.
Nosredna

Lol 2 минус для правильного решения;] Я исправил излишне два прохода, делал это быстро, но все же это работает и до сих пор является самым коротким решением.
Thinker

каждый доступ к b требует как минимум log (len (b)), так что O (n) может быть немного оптимистичным
Nicolas78,

nicolas78: Если массив маленький, это не имеет значения. Так что это зависит от вашего проекта.
Мыслитель,

7

Поскольку я использую эту функцию в качестве теста для интервьюеров, я публикую свое решение:

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

Попробуем здесь декларативный подход. Это решение создает объект для подсчета вхождений каждого слова. Затем фильтрует объект до массива, сравнивая общее количество вхождений каждого слова с наибольшим значением, найденным в объекте.

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

Пожалуйста, объясните свой ответ
Харис

Я бы избегал вычисления максимума в цикле фильтрации и удалял оператор карты значений ключей. Хотя этот ответ не самый эффективный, он не так плох, как фильтрация в редукторе, и приятный и читаемый imho. const maxValue = Math.max (... Object.values ​​(total)); const results = keys.filter (x => totals [x] === maxValue);
milesaron

3

Время для другого решения:

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

Если краткость имеет значение (а это не так), то:

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

Если необходимо избегать несуществующих членов (например, разреженного массива), требуется дополнительный тест 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

Другие ответы здесь вернут undefined .


@ Jonah - краткость сама по себе бессмысленна и обычно затрудняет чтение и сопровождение кода. Конечно, более подробный код не обязательно лучше, потому что он длиннее. Но эти критерии сами по себе обходятся гораздо более важными критериями, такими как ясность и ремонтопригодность.
RobG

Очевидно, плотная, загадочная краткость никогда не является целью. Но в целом, учитывая две версии одного и того же кода с примерно одинаковой плотностью, более короткая версия обычно яснее и лучше. Я не говорю, что это правило , но корреляция сильная. На самом деле, я бы сказал , что нет другого одного индикатора так сильно коррелирует с дискретностью. Вот почему каждый программист любит удалять код. Вот почему большинство изменений в Code Review короче оригинала.
Иона

3

Другое решение JS от: https://www.w3resource.com/javascript-exercises/javascript-array-exercise-8.php

Можете попробовать и это:

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

Вот еще один способ ES6 сделать это со сложностью 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
}

Проблема с этим решением заключается в том, что слова «max» и «mode» не будут учитываться, поскольку это часть логики карты ...
Пабло

2

Вот мое решение этой проблемы, но с числами и с использованием новой функции «Установить». Это не очень производительно, но мне определенно было очень весело писать это, и он поддерживает несколько максимальных значений.

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]

Кстати, не используйте это для производства, это просто иллюстрация того, как вы можете решить эту проблему только с помощью функций ES6 и Array.


2

Вот мое решение: -

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

Ради действительно легкого для чтения, поддерживаемого кода я делюсь следующим:

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

Надеюсь, это кому-то поможет;)!


2

Это решение может возвращать несколько элементов массива в случае ничьей. Например, массив

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

имеет два значения режима: 3и 6.

Вот решение.

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;

Примечание: ct - это длина массива.

function getMode()
{
    for (var i = 0; i < ct; i++)
    {
        value = num[i];
        if (i != ct)
        {
            while (value == num[i + 1])
            {
                c = c + 1;
                i = i + 1;
            }
        }
        if (c > greatest)
        {
            greatest = c;
            mode = value;
        }
        c = 0;
    }
}

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

Попробуйте тоже, это не касается версии браузера учетной записи.

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

Обратите внимание, что эта функция возвращает последнее появление в массиве, когда 2 или более записей появляются одинаковое количество раз!


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

Вот современная версия со встроенными картами (так что она работает не только с вещами, которые можно преобразовать в уникальные строки):

'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

Думаю, у вас есть два подхода. У обоих есть преимущества.

Отсортируйте, затем Подсчитайте или Прокрутите и используйте хеш-таблицу, чтобы сделать подсчет за вас.

Хеш-таблица хороша тем, что после завершения обработки у вас также есть все отдельные элементы. Если бы у вас были миллионы элементов, хеш-таблица могла бы использовать много памяти, если скорость дублирования низкая. Подход «сортировка, затем подсчет» будет иметь гораздо более контролируемый объем памяти.


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

Вы можете попробовать это:

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

Вы можете решить это за 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" );

Просто скопируйте и вставьте в хромированную консоль, чтобы запустить приведенный выше код.


0

Эта функция является универсальной для каждого типа информации. Он считает появление элементов, а затем возвращает массив с максимальным количеством встречающихся элементов.

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

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

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

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

  return ret_val;
}

0
function 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

Вот мой путь. Пытаюсь сгруппировать данные кулаком.

const _ = require("underscore")

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

GroupResult должен быть

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

Затем найдите свойство, имеющее самый длинный массив

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

Полный код выглядит как

const _ = require("underscore")

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

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

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

С ES6 вы можете связать метод следующим образом:

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

Если два элемента имеют одно и то же вхождение, он вернет их оба. И он работает с любым типом элемента.


вы не должны использовать переменную arrвнутри области, где эта переменная уже определена как параметр. Это может привести к ошибкам в зависимости от того, какой браузер используется.
mesqueeb

На что arrссылается arr.indexOf(cur)? Верхний параметр или тот, который находится внутри сокращения ??
mesqueeb
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.