如何获取数组中的模式

how to get mode in array

关于如何在数组中获取模式,我已经苦恼了一段时间。数组中相同的元素将放在一起。 对于前。 [Alex, Steven, Georg, Alice, Alex, Georg]; return 将是: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;}

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

我自己是 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;
}

您可以使用 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);

这是一个简单的递归解决方案,它似乎是您在此处看到的四个答案中最快的: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));

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

例如,如果您的名称数组在第二个 "Alex" 上,并且您遍历结果数组并发现 "Alex:1" 已经存在,则将值更改为 "Alex:2"(你将不得不为此做一些字符串解析)。

如果该名称不存在,请将其添加到末尾,如“:1”

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

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

另一种方法是创建一个接受数组的函数,将每个唯一的数组值分配给一个对象 属性 如果它已经存在,则将对象属性值增加一个,就像这样;

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
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 函数在聚合中有很大帮助。

我发现的方式与已接受的答案非常相似,但我想我会补充一点,如果没有项目重复,或者没有单个项目重复最多,那么就没有模式,所以我的函数会检查它并且 returns 如果是这种情况则为 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;
}

这是我的方法,我尝试了使用 reduce 的“函数式”风格。它还支持多模式,因此它将 return 一系列模式。

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
}