【问题标题】:how to get mode in array如何在数组中获取模式
【发布时间】:2015-12-23 13:24:38
【问题描述】:

关于如何在数组中获取模式,我已经有一段时间了。数组中相同的元素将放在一起。 例如。 [亚历克斯,史蒂文,乔治,爱丽丝,亚历克斯,乔治]; 返回将是:Alex:2,Steven:1,Georg:2,Alice:1;

我编写了代码,但它只适用于从 1 到 10 的数字。而且肯定有更好的方法。

(我认为您不需要我的代码,但无论如何都会粘贴它。)

var mode = function (data){
            var result1 = data.filter(function (verde) {return verde === 1});
            var result2 = data.filter(function (verde) {return verde === 2});
            var result3 = data.filter(function (verde) {return verde === 3});
            var result4 = data.filter(function (verde) {return verde === 4});
            var result5 = data.filter(function (verde) {return verde === 5});
            var result6 = data.filter(function (verde) {return verde === 6});
            var result7 = data.filter(function (verde) {return verde === 7});
            var result8 = data.filter(function (verde) {return verde === 8});
            var result9 = data.filter(function (verde) {return verde === 9});

            var nyadata = [result1.length, result2.length,
                           result3.length, result4.length,
                           result5.length, result6.length,
                           result7.length, result8.length,
                           result9.length];

            var nyarreymax = Math.max.apply(Math, nyadata);

            if (nyarreymax === result1.length){return 1;}
            if (nyarreymax === result2.length){return 2;}
            if (nyarreymax === result3.length){return 3;}
            if (nyarreymax === result4.length){return 4;}
            if (nyarreymax === result5.length){return 5;}
            if (nyarreymax === result6.length){return 6;}
            if (nyarreymax === result7.length){return 7;}
            if (nyarreymax === result8.length){return 8;}
            if (nyarreymax === result9.length){return 9;} 
            else { return  false;}

希望您能帮助我了解通常适用于字符串和所有整数的代码。

【问题讨论】:

  • 我有点不确定你在问什么,你是在寻找数组中项目的迭代计数吗?如果是这样的话;这可能会有所帮助:stackoverflow.com/questions/19395257/…
  • 该代码似乎缺少右花括号}

标签: javascript arrays mode


【解决方案1】:

这是我的方法,我尝试了使用 reduce 的“函数式”样式。它还支持多模式,因此它会返回一个模式数组。

export function mode(vector) {
if (vector.length === 0) return undefined

 return (vector.reduce((accu, curr) => {
    const freqsMap = accu.freqsMap
    freqsMap.set(curr, (freqsMap.get(curr) || 0) + 1)

    const maxCount = freqsMap.get(curr) > accu.maxCount
        ? freqsMap.get(curr)
        : accu.maxCount
    const modes = freqsMap.get(curr) === accu.maxCount
        ? [...accu.modes, curr]
        : freqsMap.get(curr) > accu.maxCount
            ? [curr]
            : accu.modes

    return { freqsMap, maxCount, modes }
 }, { freqsMap: new Map(), maxCount: 1, modes: []})).modes
}

【讨论】:

    【解决方案2】:

    我发现的方式与接受的答案非常相似,但是我想我会补充一点,如果没有项目重复,或者没有单个项目重复最多,则没有模式,所以我的函数会检查并返回 null 如果是案例。

    function calcMode(data) {
      let counts = {};
      data.forEach((d) => {
        if (counts[d] === undefined) {
          counts[d] = 0;
        }
        counts[d] += 1;
      });
      let mode,
        max = 0,
        repeats = 0;
      Object.keys(counts).forEach((k) => {
        if (counts[k] > max) {
          max = counts[k];
          mode = k;
          repeats = 0;
        } else if (counts[k] == max) repeats += 1;
      });
      if (!repeats) {
        if (isNaN(mode)) return mode;
        else return +mode;
      } else return null;
    }
    

    【讨论】:

      【解决方案3】:

      这是一个简单的递归解决方案,它似乎是您在此处看到的四个答案中最快的:http://jsperf.com/array-mode

      var a = ["Alex", "Steven", "Georg", "Alice", "Alex", "Georg"];
      
      function getMode(a, result) {
        result = result || {};
        
        if (a.length === 0){
          return result;
        }
        
        var head = a.shift();
        if (result[head]){
          result[head]++;
        }
        else{
          result[head] = 1;
        }
        return getMode(a, result);
      }
      
      console.log(getMode(a));

      【讨论】:

        【解决方案4】:
        var numbers = [1,2,2,3,4,5];
        var counts = numbers.reduce((counts, e) => { counts[e] = counts[e] ? counts[e] + 1 : 1; return counts; }, {});
        var mode = Object.keys(counts).reduce((a, b) => (counts[a] > counts[b] ? a : b ));
        console.log(mode);
        

        Reduce 函数对聚合有很大帮助。

        【讨论】:

          【解决方案5】:

          您可以使用 reduce() 尝试此操作,请查看您的控制台显示计数值。

          演示http://jsfiddle.net/ak69f/

          var array_elements = ['Alex', 'Steven', 'Georg', 'Alice', 'Alex', 'Georg'];
          
          var result = array_elements.reduce(function(p, c){
              if (c in p) {
                 p[c]++;
              } else {
                  p[c]=1;
              }
              return p;
          }, []);
          
          console.log(result);
          

          【讨论】:

            【解决方案6】:

            另一种方法是创建一个函数,该函数接收您的数组,将每个唯一的数组值分配给一个对象属性,如果它已经存在,则将对象属性值加一,如下所示;

            function countArray(array){
                    var results = {};
            
                    for(var x = 0; x < array.length; x++){
            
                        if(results[array[x]] == undefined){
                            results[array[x]] = 1;
                        }else{
                            results[array[x]] += 1;
                        }
                    }
            
                    return results;
                }
            
                var checkArray = countArray(['alex', 'george', 'steve', 'alex']);
            
                console.log(checkArray); 
                // outputs "Object {alex: 2, george: 1, steve: 1}"
            

            然后您可以根据需要通过调用访问结果

            console.log(checkArray.alex); // outputs 2
            

            【讨论】:

              【解决方案7】:

              首先,定义一个保存结果的新数组。 遍历您的名称数组。在每个循环内部,遍历结果数组。如果您的名称数组中的当前名称存在于结果数组中,请更改值。

              例如,如果您的名称数组位于第二个“Alex”上,并且您遍历结果数组并发现“Alex:1”已经存在,请将值更改为“Alex:2”(您必须为此做一些字符串解析)。

              如果名称不存在,则将其添加到末尾作为“:1”

              然后如果你想返回模式,你将不得不编写另一个循环来找到最大出现次数。有一个变量来跟踪具有最高数字的名称的数组位置(假设它称为maxIndex)。对于数组中的每一项,将其与maxIndex 处的数组值进行比较。如果更高,请将maxIndex 重置为当前索引。如果等于或小于,则移动到数组的下一项。

              我知道这很罗嗦,所以如果您有任何问题,请告诉我。

              【讨论】:

              • 最好使用对象来存储结果,因为您不必遍历它来查找现有匹配项。
              • 很公平,但我的印象是 OP 希望将结果作为字符串数组。不过,您的方法看起来更干净。
              【解决方案8】:

              我自己是 js 的初学者,不久前正在寻找同样的解决方案。这是我发现的,应该是您正在寻找的:

              function findMode(arr) {
                  var map = {};
                  for (var i = 0; i < arr.length; i++) {
                      if (map[arr[i]] === undefined) {
                          map[arr[i]] = 0;
                      }
                      map[arr[i]] += 1;
                  }
                  var greatestFreq = 0;
                  var mode;
                  for (var prop in map) {
                      if (map[prop] > greatestFreq) {
                          greatestFreq = map[prop];
                          mode = prop;
                      }
                  }
                  return mode;
              }
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多