Get the element with the highest occurrence in an array

后端 未结 30 1235
野性不改
野性不改 2020-11-22 11:17

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

For example, in

[\'pear\', \'a         


        
相关标签:
30条回答
  • 2020-11-22 11:55
    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;
    }
    
    0 讨论(0)
  • 2020-11-22 11:56

    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.

    0 讨论(0)
  • 2020-11-22 11:57

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

    0 讨论(0)
  • 2020-11-22 11:59

    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.

    0 讨论(0)
  • 2020-11-22 12:02

    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
    
    0 讨论(0)
  • 2020-11-22 12:02

    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.

    0 讨论(0)
提交回复
热议问题