用JavaScript查找模式的最简单方法

时间:2018-10-19 19:00:04

标签: javascript

我是JavaScript的初学者,我正在尝试编写代码以查找模式。我的代码正在运行,但是只有连续写入时才能找到模式。但是,当存在像这样的a = [1,2,3,4,5,2]数组时,它找不到模式。

由于我是初学者,所以我不想写任何复杂的东西,而是想以最简单的方式学习它。有人可以帮我吗?

list = [1,2,3,4,5,6,7,7]
var empty = []
i = 0
max = 0
while (i<list.length){

   if (list[i]==list[i+1]){
       empty = list[i] 
   i += 1
    }else{
      i +=1
      }

 }
 document.write(empty) 

2 个答案:

答案 0 :(得分:1)

您的代码假定参数数组是预先排序的,这是一个冒险且局限性的假设,并且似乎仅适用于排序后的数组(反例:[1,1,1,7,7]错误地报告了7作为模式)。

如果您希望继续使用此方法,那么您将走在正确的轨道上,但是您需要跟踪当前/最佳条纹,当前/最佳元素,并对返回的最长条纹进行最终检查。结果:

var mode = a => {
  a.sort((x, y) => x - y);

  var bestStreak = 1;
  var bestElem = a[0];
  var currentStreak = 1;
  var currentElem = a[0];

  for (let i = 1; i < a.length; i++) {
    if (a[i-1] !== a[i]) {
      if (currentStreak > bestStreak) {
        bestStreak = currentStreak;
        bestElem = currentElem;
      }

      currentStreak = 0;
      currentElem = a[i];
    }

    currentStreak++;
  }

  return currentStreak > bestStreak ? currentElem : bestElem;
};


console.log(mode([1,2,3,4,5,6,7,7]));
console.log(mode([1,1,1,4,5,6,7,7]));
console.log(mode([1,2,3,3,3,6,3,7]));
console.log(mode([1,3,3,4,5,2,2,1]));
console.log(mode([]));

话虽如此,排序是非线性操作,所以我建议尝试另一种方法。

这个想法是使用一个对象对数组中每个项目的出现次数进行计数,然后采用计数最高的元素。我使用reduce来执行以下两项操作:

const mode = a => 
  Object.values(
    a.reduce((count, e) => {
      if (!(e in count)) {
        count[e] = [0, e];
      }
      
      count[e][0]++;
      return count;
    }, {})
  ).reduce((a, v) => v[0] < a[0] ? a : v, [0, null])[1];
;

console.log(mode([1,2,3,4,5,6,7,7]));
console.log(mode([1,1,1,4,5,6,7,7]));
console.log(mode([1,2,3,3,3,6,3,7]));
console.log(mode([1,3,3,4,5,2,2,1]));
console.log(mode([]));

或者,出于可读性考虑,写同样的东西而没有reduce

const mode = a => {
  const count = {};
  
  a.forEach(e => {
    if (!(e in count)) {
      count[e] = 0;
    }

    count[e]++;
  });

  let bestElement;
  let bestCount = 0;

  Object.entries(count).forEach(([k, v]) => {
    if (v > bestCount) {
      bestElement = k;
      bestCount = v;
    }
  });
  
  return bestElement;
};

console.log(mode([1,2,3,4,5,6,7,7]));
console.log(mode([1,1,1,4,5,6,7,7]));
console.log(mode([1,2,3,3,3,6,3,7]));
console.log(mode([1,3,3,4,5,2,2,1]));
console.log(mode([]));

请注意,在平局的情况下,这些方法不会选择相同的模式。您可能希望添加一个数组来跟踪所有模式,或者更改算法以选择第一个或最后一个出现的模式以满足您的需求。

答案 1 :(得分:0)

使用哈希

list = [1,2,3,4,5,6,7,7]
counts = {}
list.forEach(function(e) {
  if(counts[e] === undefined) {
    counts[e] = 0
  }
  counts[e] += 1
})

结果如下:

{1:1,2:1,3:1,4:1,5:1,6:1,7:2}

此相关问题涉及在哈希中查找最大值和最小值,这实际上是您在此末尾所做的事情。

Fast way to get the min/max values among properties of object