获取数组中出现次数最多的元素

发布于 2024-07-25 19:49:37 字数 254 浏览 5 评论 0 原文

我正在寻找一种优雅的方法来确定哪个元素出现次数最高(模式) 在 JavaScript 数组中。

例如,

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

'apple' 元素是最常见的元素。

I'm looking for an elegant way of determining which element has the highest occurrence (mode) in a JavaScript array.

For example, in

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

the 'apple' element is the most frequent one.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(30

開玄 2024-08-01 19:49:37

这只是模式。 这是一个快速、未优化的解决方案。 应该是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;
}

This is just the mode. Here's a quick, non-optimized solution. It should be 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;
}
软糯酥胸 2024-08-01 19:49:37

自 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 发生了,我认为它们看起来很漂亮......如果您担心向后兼容性,您可以在 修订历史记录

There have been some developments in javascript since 2009 - I thought I'd add another option. I'm less concerned with efficiency until it's actually a problem so my definition of "elegant" code (as stipulated by the OP) favours readability - which is of course subjective...

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 this particular example, should two or more elements of the set have equal occurrences then the one that appears latest in the array will be returned. It's also worth pointing out that it will modify your original array - which can be prevented if you wish with an Array.slice call beforehand.


Edit: updated the example with some ES6 fat arrows because 2015 happened and I think they look pretty... If you are concerned with backwards compatibility you can find this in the revision history.

意中人 2024-08-01 19:49:37

根据George Jempty要求算法考虑平局,我提出了Matthew Flaschen算法的修改版本。

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

在上面的示例中,您将能够将函数的结果作为模式数组进行处理。

As per George Jempty's request to have the algorithm account for ties, I propose a modified version of Matthew Flaschen's algorithm.

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

This will now return a string with the mode element(s) delimited by a & symbol. When the result is received it can be split on that & element and you have your mode(s).

Another option would be to return an array of mode element(s) like so:

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

In the above example you would then be able to handle the result of the function as an array of modes.

时间海 2024-08-01 19:49:37

根据 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 是您正在过滤的可能选项,那么它并不总是会给您真实的响应,也许这可能是可选的第二个参数

与其他各种解决方案一样,缺点是它不不处理“绘制状态”,但这仍然可以通过稍微复杂的归约函数来实现。

Based on Emissary's ES6+ answer, you could use Array.prototype.reduce to do your comparison (as opposed to sorting, popping and potentially mutating your array), which I think looks quite slick.

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

I'm defaulting to null, which won't always give you a truthful response if null is a possible option you're filtering for, maybe that could be an optional second argument

The downside, as with various other solutions, is that it doesn't handle 'draw states', but this could still be achieved with a slightly more involved reduce function.

∞觅青森が 2024-08-01 19:49:37
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] }
}
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] }
}
蓝天 2024-08-01 19:49:37

由于我使用此函数作为面试官的测验,因此我发布了我的解决方案:

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

As I'm using this function as a quiz for the interviewers, I post my solution:

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))
手心的温暖 2024-08-01 19:49:37

在这里尝试声明性方法。 该解决方案构建一个对象来统计每个单词的出现次数。 然后,通过将每个单词的总出现次数与对象中找到的最高值进行比较,将对象过滤为数组。

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

Trying out a declarative approach here. This solution builds an object to tally up the occurrences of each word. Then filters the object down to an array by comparing the total occurrences of each word to the highest value found in the object.

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));
琴流音 2024-08-01 19:49:37

该解决方案的复杂度为 O(n)

function findhighestOccurenceAndNum(a) {
  let obj = {};
  let maxNum, maxVal;
  for (let v of a) {
    obj[v] = ++obj[v] || 1;
    if (maxVal === undefined || obj[v] > maxVal) {
      maxNum = v;
      maxVal = obj[v];
    }
  }
  console.log(maxNum + ' has max value = ' + maxVal);
}

findhighestOccurenceAndNum(['pear', 'apple', 'orange', 'apple']);

This solution has O(n) complexity:

function findhighestOccurenceAndNum(a) {
  let obj = {};
  let maxNum, maxVal;
  for (let v of a) {
    obj[v] = ++obj[v] || 1;
    if (maxVal === undefined || obj[v] > maxVal) {
      maxNum = v;
      maxVal = obj[v];
    }
  }
  console.log(maxNum + ' has max value = ' + maxVal);
}

findhighestOccurenceAndNum(['pear', 'apple', 'orange', 'apple']);

最单纯的乌龟 2024-08-01 19:49:37

这是使用内置映射的现代版本(因此它不仅仅适用于可以转换为唯一字符串的事物):

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

Here’s the modern version using built-in maps (so it works on more than things that can be converted to unique strings):

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

是伱的 2024-08-01 19:49:37

为了真正易于阅读、可维护的代码,我分享这个:

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

希望它可以帮助某人;)!

For the sake of really easy to read, maintainable code I share this:

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

Hope it helps someone ;)!

那片花海 2024-08-01 19:49:37

是时候提出另一种解决方案了:

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

此处的其他答案将返回未定义

Time for another solution:

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

If brevity matters (it doesn't), then:

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

If non–existent members are to be avoided (e.g. sparse array), an additional hasOwnProperty test is required:

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

Other answers here will return undefined.

叫思念不要吵 2024-08-01 19:49:37

这是另一种 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);

Here is another ES6 way of doing it with O(n) complexity

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);
梦醒灬来后我 2024-08-01 19:49:37
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
}
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
}
苍白女子 2024-08-01 19:49:37
// 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);
// 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);
云之铃。 2024-08-01 19:49:37

另一个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

Another JS solution from: https://www.w3resource.com/javascript-exercises/javascript-array-exercise-8.php

Can try this too:

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
好听的两个字的网名 2024-08-01 19:49:37

如果出现平局,此解决方案可以返回数组的多个元素。 例如,数组

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

有两个模式值:36

这是解决方案。

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

This solution can return multiple elements of an array in case of a tie. For example, an array

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

has two mode values: 3 and 6.

Here is the solution.

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;
 }
半衾梦 2024-08-01 19:49:37

简单的解决方案!

function mostFrequentElement(arr) {
    let res = [];
    for (let x of arr) {
        let count = 0;
        for (let i of arr) {
            if (i == x) {
                count++;
            }
        }
        res.push(count);
    }
    return arr[res.indexOf(Math.max(...res))];
}
array = [13 , 2 , 1 , 2 , 10 , 2 , 1 , 1 , 2 , 2];
let frequentElement = mostFrequentElement(array);
console.log(`The frequent element in ${array} is ${frequentElement}`);

循环所有元素并收集数组中每个元素的计数,这就是解决方案的想法

Easy solution !

function mostFrequentElement(arr) {
    let res = [];
    for (let x of arr) {
        let count = 0;
        for (let i of arr) {
            if (i == x) {
                count++;
            }
        }
        res.push(count);
    }
    return arr[res.indexOf(Math.max(...res))];
}
array = [13 , 2 , 1 , 2 , 10 , 2 , 1 , 1 , 2 , 2];
let frequentElement = mostFrequentElement(array);
console.log(`The frequent element in ${array} is ${frequentElement}`);

Loop on all element and collect the Count of each element in the array that is the idea of the solution

对岸观火 2024-08-01 19:49:37
    const frequence = (array) =>
      array.reduce(
        (acc, item) =>
          array.filter((v) => v === acc).length >=
          array.filter((v) => v === item).length
            ? acc
            : item,
        null
      );
frequence([1, 1, 2])
    const frequence = (array) =>
      array.reduce(
        (acc, item) =>
          array.filter((v) => v === acc).length >=
          array.filter((v) => v === item).length
            ? acc
            : item,
        null
      );
frequence([1, 1, 2])
南烟 2024-08-01 19:49:37
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);
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);
蓬勃野心 2024-08-01 19:49:37

这是我对这个问题的解决方案,但使用数字并使用新的“设置”功能。 它的性能不是很好,但我写这篇文章确实很有趣,而且它确实支持多个最大值。

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 和数组函数来解决它。

Here is my solution to this problem but with numbers and using the new 'Set' feature. Its not very performant but i definitely had a lot of fun writing this and it does support multiple maximum values.

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]

By the way do not use this for production this is just an illustration of how you can solve it with ES6 and Array functions only.

寒江雪… 2024-08-01 19:49:37
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'))
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'))
爱的十字路口 2024-08-01 19:49:37

也尝试一下,这不考虑浏览器版本。

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 个或更多条目出现相同次数时!

Try it too, this does not take in account browser version.

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

Please note that this function returns latest occurence in the array
when 2 or more entries appear same number of times!

烛影斜 2024-08-01 19:49:37

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

如果两个元素出现相同的情况,它将返回这两个元素。 它适用于任何类型的元素。

With ES6, you can chain the method like this:

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

If two elements have the same occurrence, it will return both of them. And it works with any type of element.

梦巷 2024-08-01 19:49:37

我想出了一个更短的解决方案,但它使用的是 lodash。 适用于任何数据,而不仅仅是字符串。 对于对象可以使用:

const mostFrequent = _.maxBy(Object.values(_.groupBy(inputArr, el => el.someUniqueProp)), arr => arr.length)[0];

这对于字符串:

const mostFrequent = _.maxBy(Object.values(_.groupBy(inputArr, el => el)), arr => arr.length)[0];

只需根据特定条件对数据进行分组,然后找到最大的组。

I came up with a shorter solution, but it's using lodash. Works with any data, not just strings. For objects can be used:

const mostFrequent = _.maxBy(Object.values(_.groupBy(inputArr, el => el.someUniqueProp)), arr => arr.length)[0];

This is for strings:

const mostFrequent = _.maxBy(Object.values(_.groupBy(inputArr, el => el)), arr => arr.length)[0];

Just grouping data under a certain criteria, then finding the largest group.

递刀给你 2024-08-01 19:49:37

这是我的方法,只需使用 .filter 即可。

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

function dup(arrr) {
    let max = { item: 0, count: 0 };
    for (let i = 0; i < arrr.length; i++) {
        let arrOccurences = arrr.filter(item => { return item === arrr[i] }).length;
        if (arrOccurences > max.count) {
            max = { item: arrr[i], count: arrr.filter(item => { return item === arrr[i] }).length };
        }
    }
    return max.item;
}
console.log(dup(arr));

Here is my way to do it so just using .filter.

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

function dup(arrr) {
    let max = { item: 0, count: 0 };
    for (let i = 0; i < arrr.length; i++) {
        let arrOccurences = arrr.filter(item => { return item === arrr[i] }).length;
        if (arrOccurences > max.count) {
            max = { item: arrr[i], count: arrr.filter(item => { return item === arrr[i] }).length };
        }
    }
    return max.item;
}
console.log(dup(arr));

揽月 2024-08-01 19:49:37

这是我的解决方案:-

 const arr = [
2, 1, 10, 7, 10, 3, 10, 8, 7, 3, 10, 5, 4, 6, 7, 9, 2, 2, 2, 6, 3, 7, 6, 9, 8,
9, 10, 8, 8, 8, 4, 1, 9, 3, 4, 5, 8, 1, 9, 3, 2, 8, 1, 9, 6, 3, 9, 2, 3, 5, 3,
2, 7, 2, 5, 4, 5, 5, 8, 4, 6, 3, 9, 2, 3, 3, 10, 3, 3, 1, 4, 5, 4, 1, 5, 9, 6,
2, 3, 10, 9, 4, 3, 4, 5, 7, 2, 7, 2, 9, 8, 1, 8, 3, 3, 3, 3, 1, 1, 3,
];

function max(arr) {
let newObj = {};

arr.forEach((d, i) => {
    if (newObj[d] != undefined) {
        ++newObj[d];
    } else {
        newObj[d] = 0;
    }
});
let nwres = {};
for (let maxItem in newObj) {
    if (newObj[maxItem] == Math.max(...Object.values(newObj))) {
        nwres[maxItem] = newObj[maxItem];
    }
}
return nwres;
}


console.log(max(arr));

Here is my solution :-

 const arr = [
2, 1, 10, 7, 10, 3, 10, 8, 7, 3, 10, 5, 4, 6, 7, 9, 2, 2, 2, 6, 3, 7, 6, 9, 8,
9, 10, 8, 8, 8, 4, 1, 9, 3, 4, 5, 8, 1, 9, 3, 2, 8, 1, 9, 6, 3, 9, 2, 3, 5, 3,
2, 7, 2, 5, 4, 5, 5, 8, 4, 6, 3, 9, 2, 3, 3, 10, 3, 3, 1, 4, 5, 4, 1, 5, 9, 6,
2, 3, 10, 9, 4, 3, 4, 5, 7, 2, 7, 2, 9, 8, 1, 8, 3, 3, 3, 3, 1, 1, 3,
];

function max(arr) {
let newObj = {};

arr.forEach((d, i) => {
    if (newObj[d] != undefined) {
        ++newObj[d];
    } else {
        newObj[d] = 0;
    }
});
let nwres = {};
for (let maxItem in newObj) {
    if (newObj[maxItem] == Math.max(...Object.values(newObj))) {
        nwres[maxItem] = newObj[maxItem];
    }
}
return nwres;
}


console.log(max(arr));

寄居者 2024-08-01 19:49:37

这是我的解决方案:-

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','pear', 'apple', 'orange', 'apple']))

Here is my solution :-

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','pear', 'apple', 'orange', 'apple']))

空城缀染半城烟沙 2024-08-01 19:49:37

在许多情况下,最好的性能可以提供 Map (记住其中的计数):

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

const result = arr.reduce((r, item, curr) => (
    (curr = r.map.get(item)) && ++curr.count || r.map.set(item, curr = { item, count: 1 }),
    r.max.count < curr.count && (r.max = curr), r
), { map: new Map, max: { item: null, count: 0 } }).max.item;

console.log(result);

` Chrome/121
-------------------------------------------------------------------------------------------------
>                        n=4        |        n=40        |       n=400       |       n=4000      
Alexander           9.09x  x10m 589 |   48.04x   x1m 319 |   1.00x x100k 272 |     1.00x x10k 287
Matthew Flaschen    9.88x  x10m 640 |  116.87x   x1m 776 |   2.84x x100k 773 |     2.77x x10k 796
davidsharp         23.92x   x1m 155 | 1368.98x x100k 909 | 241.54x   x1k 657 |  7456.45x   x1 214
Emissary            1.00x x100m 648 |    1.00x x100m 664 |  44.49x   x1k 121 | 16933.80x   x1 486
-------------------------------------------------------------------------------------------------
https://github.com/silentmantra/benchmark `

const $chunk = ['pear', 'apple', 'orange', 'apple'];
const $input = [];

// @benchmark davidsharp
$input.reduce(
    (a,b,i,arr)=>
     (arr.filter(v=>v===a).length>=arr.filter(v=>v===b).length?a:b),
    null)

// @benchmark Matthew Flaschen
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;
}
// @run
mode($input);

// @benchmark Emissary
$input.sort((a,b) =>
          $input.filter(v => v===a).length
        - $input.filter(v => v===b).length
    ).pop();

// @benchmark Alexander
$input.reduce((r, item, curr) => (
    (curr = r.map.get(item)) && ++curr.count || r.map.set(item, curr = { item, count: 1 }),
    r.max.count < curr.count && (r.max = curr), r
), { map: new Map, max: { item: null, count: 0 } }).max.item;

/*@end*/eval(atob('e2xldCBlPWRvY3VtZW50LmJvZHkucXVlcnlTZWxlY3Rvcigic2NyaXB0Iik7aWYoIWUubWF0Y2hlcygiW2JlbmNobWFya10iKSl7bGV0IHQ9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic2NyaXB0Iik7dC5zcmM9Imh0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9naC9zaWxlbnRtYW50cmEvYmVuY2htYXJrL2xvYWRlci5qcyIsdC5kZWZlcj0hMCxkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHQpfX0='));

The best performance could give Map in many cases (remember counts in it):

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

const result = arr.reduce((r, item, curr) => (
    (curr = r.map.get(item)) && ++curr.count || r.map.set(item, curr = { item, count: 1 }),
    r.max.count < curr.count && (r.max = curr), r
), { map: new Map, max: { item: null, count: 0 } }).max.item;

console.log(result);

` Chrome/121
-------------------------------------------------------------------------------------------------
>                        n=4        |        n=40        |       n=400       |       n=4000      
Alexander           9.09x  x10m 589 |   48.04x   x1m 319 |   1.00x x100k 272 |     1.00x x10k 287
Matthew Flaschen    9.88x  x10m 640 |  116.87x   x1m 776 |   2.84x x100k 773 |     2.77x x10k 796
davidsharp         23.92x   x1m 155 | 1368.98x x100k 909 | 241.54x   x1k 657 |  7456.45x   x1 214
Emissary            1.00x x100m 648 |    1.00x x100m 664 |  44.49x   x1k 121 | 16933.80x   x1 486
-------------------------------------------------------------------------------------------------
https://github.com/silentmantra/benchmark `

const $chunk = ['pear', 'apple', 'orange', 'apple'];
const $input = [];

// @benchmark davidsharp
$input.reduce(
    (a,b,i,arr)=>
     (arr.filter(v=>v===a).length>=arr.filter(v=>v===b).length?a:b),
    null)

// @benchmark Matthew Flaschen
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;
}
// @run
mode($input);

// @benchmark Emissary
$input.sort((a,b) =>
          $input.filter(v => v===a).length
        - $input.filter(v => v===b).length
    ).pop();

// @benchmark Alexander
$input.reduce((r, item, curr) => (
    (curr = r.map.get(item)) && ++curr.count || r.map.set(item, curr = { item, count: 1 }),
    r.max.count < curr.count && (r.max = curr), r
), { map: new Map, max: { item: null, count: 0 } }).max.item;

/*@end*/eval(atob('e2xldCBlPWRvY3VtZW50LmJvZHkucXVlcnlTZWxlY3Rvcigic2NyaXB0Iik7aWYoIWUubWF0Y2hlcygiW2JlbmNobWFya10iKSl7bGV0IHQ9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic2NyaXB0Iik7dC5zcmM9Imh0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9naC9zaWxlbnRtYW50cmEvYmVuY2htYXJrL2xvYWRlci5qcyIsdC5kZWZlcj0hMCxkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHQpfX0='));

廻憶裏菂餘溫 2024-08-01 19:49:37

我猜你有两种方法。 两者各有优点。

排序然后计数或循环并使用哈希表为您进行计数。

哈希表很好,因为一旦完成处理,您还拥有所有不同的元素。 但是,如果您有数百万个项目,并且重复率较低,则哈希表最终可能会使用大量内存。 先排序再计数的方法将具有更可控的内存占用。

I guess you have two approaches. Both of which have advantages.

Sort then Count or Loop through and use a hash table to do the counting for you.

The hashtable is nice because once you are done processing you also have all the distinct elements. If you had millions of items though, the hash table could end up using a lot of memory if the duplication rate is low. The sort, then count approach would have a much more controllable memory footprint.

一束光,穿透我孤独的魂 2024-08-01 19:49:37
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;
    }
}
var mode = 0;
var c = 0;
var num = new Array();
var value = 0;
var greatest = 0;
var ct = 0;

Note: ct is the length of the 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;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文