JavaScript For循环数组迭代问题 - 使用一次循环还是两次循环

6
这个问题的目标是遍历一个列表,找到列表中最大的值,然后报告最高值的索引值。我能够使用两个for循环解决这个问题:
var scores = [60, 50, 58, 54, 54, 58, 50, 52, 54, 48, 69, 34, 55, 51, 52, 44, 51, 69, 64, 66, 55, 52, 44, 18, 41, 53, 55, 61, 51, 44];
var highscore = 0;
var highscoreSolutions = [];

for (var i = 0; i < scores.length; i++){
 if (scores[i] > highscore){
     highscore = scores[i];
 } 
}

for (var i = 0; i < scores.length; i++){
 if (scores[i] == highscore){
    highscoreSolutions.push(i);
   }
  }

console.log(highscore);
console.log(highscoreSolutions);

我最初尝试使用一个for循环来解决这个问题,但我遇到了一些初始化问题,即无论如何,第一个索引值都会被包含在最高分数列表中:

var scores = [60, 50, 58, 54, 54, 58, 50, 52, 54, 48, 69, 34, 55, 51, 52, 44, 51, 69, 64, 66, 55, 52, 44, 18, 41, 53, 55, 61, 51, 44];
var highscore = 0;
var highscoreSolutions = [];

for (var i = 0; i < scores.length; i++){
  if (scores[i] >= highscore){
    highscore = scores[i];
    highscoreSolutions.push(i);
  } 
}

console.log(highscore);
console.log(highscoreSolutions);

我不确定如何解决添加0索引值的问题(没有使用两个单独的for循环)。有人能帮我吗?非常感谢!:)

3个回答

3

当你找到一个新的最高值时,你需要清除列表:

var scores = [60, 50, 58, 54, 54, 58, 50, 52, 54, 48, 69, 34, 55, 51, 52, 44, 51, 69, 64, 66, 55, 52, 44, 18, 41, 53, 55, 61, 51, 44];
var highscore = 0;
var highscoreSolutions = [];
var score;

for (var i = 0; i < scores.length; i++) {
  score = scores[i];
  if (score == highscore) {
    highscore = score;
    highscoreSolutions.push(i);
  } else if (score > highscore) {
    highscore = score;
    // We have a new highest score, so all the values currently in the array
    // need to be removed
    highscoreSolutions = [i];
  }
}

snippet.log(highscore);
snippet.log(highscoreSolutions.join(", "));
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>


1
非常整洁,不过我会从 highscore = score[0]highscoreSolutions = [0] 开始,而不是从 0 开始。 - T.J. Crowder
我认为highscoreSolutions的目的是显示高分计算过程的进展情况-即在循环迭代中被视为高分的内容。 - Mahout
@Mahout: 对我来说,“...然后报告最高值的索引值”听起来完全不是那样。 - T.J. Crowder
1
@T.J.Crowder - 我可能误解了你的代码,但它似乎只会报告索引号为17的最高分数,而应该还输出索引值为10的最高分数。不过我认为这只是一个打字错误 - highestSolutions = [i] 应该改为 highscoreSolutions = [i] - Kiyana
1
@Kiyana:不是我的代码,是James的。而且,我认为你可能是对的,有一个笔误。编辑: 你是对的。我还纠正了另一个拼写错误,并将其转换为Stack Snippet。现在它正确地报告了索引69的位置是10和17。 - T.J. Crowder

1
这可能听起来有点复杂,但是由于您似乎正在学习JavaScript,建议您跳过使用for循环(当然,您应该知道它们的存在和用法)并学习使用函数式编程范式的JavaScript (一个很棒的交互式教程),因为这会导致更易读且更少出错的代码。
解决您问题的方法可以使用[].reduce()
function highest(numbers) {
  return numbers.reduce(function(winner, current, index) {
    if (current > winner.value) {
      return {value: current, indices: [index]};
    } else if (current === winner.value) {
      winner.indices.push(index);
      return winner;
    } else {
      return winner;
    }
  }, {value: Number.NEGATIVE_INFINITY, indices: []});
}

function highest(numbers) {
  return numbers.reduce(function(winner, current, index) {
    if (current > winner.value) {
      return {value: current, indices: [index]};
    } else if (current === winner.value) {
      winner.indices.push(index);
      return winner;
    } else {
      return winner;
    }
  }, {value: Number.NEGATIVE_INFINITY, indices: []});
}

document.querySelector('button').addEventListener('click', function() {
  var randoms = new Array(100).join(' ').split('').map(function() {return Math.ceil(Math.random() * 100)});
  document.querySelector('#array').innerHTML = JSON.stringify(randoms);
  document.querySelector('#result').innerHTML = JSON.stringify(highest(randoms));
});
<button>run</button>
<h3>the array</h3>
<pre id="array"></pre>
<h3>the result</h3>
<pre id="result"></pre>


0
var scores = [60, 50, 58, 54, 54, 58, 50, 52, 54, 48, 69, 34, 55, 51, 52, 44, 51, 69, 64, 66, 55, 52, 44, 18, 41, 53, 55, 61, 51, 44];

//clone array keeping original as scores, sort the new cloned array, grab the max value
var highscore = scores.slice(0).sort()[scores.length - 1];
var highscoreSolutions = [];

//find occurances of highscore and push to array
for (var i = 0; i < scores.length; i++){
    if (scores[i] == highscore){
        highscoreSolutions.push(i);
    }
}

alert('highscore: ' + highscore + '\nindexes: ' + highscoreSolutions)

你可以使用Array.slice(0)来克隆数组。
然后运行sort()函数,并通过检查长度-1来获取新排序数组的最后一个值。
然后循环迭代,找到高分的索引位置。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接