javascript - 是否有 for 循环或 .forEach 方法删除当前数组元素,然后让流程从同一索引继续?

标签 javascript for-loop foreach

我正在 coderbytes 解决这个问题:

使用 JavaScript 语言,让函数 SecondGreatLow(arr) 获取存储在 arr 中的数字数组,并分别返回第二小和第二大的数字,并以空格分隔。例如:如果 arr 包含 [7, 7, 12, 98, 106],则输出应为 12 98。该数组不会为空,并且至少包含 2 个数字。如果只有两个数字,事情会变得很棘手!

我的解决方案的工作原理是从数组中删除最大和最低值,然后使用数学方法返回第二高和最低值。

但是,当数组的最大或最低元素有两个或多个实例,并且它们的索引位置彼此相邻时,我相信仅删除该值的第一个实例,并且流程会跳过第二个实例实例。

有没有办法让循环运行相同的索引值两次,以便处理相邻的最大或最小值?

这是我测试过的解决方案的两次迭代..我最初尝试使用 .forEach ,第二次尝试使用 for 循环..我已经 console.logged 代码工作的情况以及它的情况并非每次尝试都如此。

我对这一切真的很陌生,在我的空闲时间里学习了将近一个月,所以解释一下自己,就好像我真的很蠢一样,这是值得赞赏的。谢谢!!!

<小时/>
// * First attempt - using .forEach method *

// outputs the second lowest value in the array
function secondLowest (arr) {
    var g = function () {
        return Math.min.apply(null, arr);
    }
    arr.forEach(function (val, indx, arr) {
        if (val === g()) {
            arr.splice(indx, 1);
        }
    });
    lowestVal = g(); // store this value to be added back in for the secondGreatest function (in case there were only two digits in the arr argument)
    return Math.min.apply(null, arr);   
}


// number trimmed from the array in the function secondLowest.. 
// to be added back in for the function secondGreatest
var lowestVal = 0


// adds back the lowest value which was trimmed..
// outputs the second greatest value
function secondGreatest (arr){
    arr.splice(0,0,lowestVal);
    var g = function () {
        return Math.max.apply(null, arr);
    }
    arr.forEach(function (val, indx, arr) {
        if (val === g()) {
            arr.splice(indx, 1);
        }
    });
    return Math.max.apply(null, arr);
}


// putting together the output
function SecondGreatLow (arr) {
    return secondLowest(arr) + " " + secondGreatest(arr);
}
console.log(SecondGreatLow([1,2,3,4,5]));
console.log(SecondGreatLow([1,1,2,2,3,3,4,4,5,5]));
<小时/>
// * Second attempt - using for loops *

// outputs the second lowest value in the array
function secondLowest (arr) {
    var g = function () {
        return Math.min.apply(null, arr);
    }
    lowestVal = g();
    for (var i = 0; i < arr.length; i++) {
        if (arr[i] === g()) {
            arr.splice(i, 1);

        }
    }
    return Math.min.apply(null, arr);   
}


// number trimmed from the array in the function secondLowest.. 
// to be added back in for the function secondGreatest
var lowestVal = 0


// adds back the lowest value which was trimmed..
// outputs the second greatest value
function secondGreatest (arr){
    arr.splice(0,0,lowestVal);
    var g = function () {
        return Math.max.apply(null, arr);
    }
    for (var i = 0; i < arr.length; i++) {
        if (arr[i] === g()) {
            arr.splice(i, 1);
        }
    }
    return Math.max.apply(null, arr);
}


// putting together the output
function SecondGreatLow (arr) {
    return secondLowest(arr) + " " + secondGreatest(arr);
}
console.log(SecondGreatLow([1,2,3,4,5]));
console.log(SecondGreatLow([1,1,2,2,3,3,4,4,5,5]));

我尝试使用删除运算符来保持参数数组长度一致(而不是使用拼接来缩短它,我认为这允许相邻值传递到已删除元素的索引位置,并且不会在下一次遍历中进行处理) for 循环或 forEach 方法),但 Math.min/max.apply 方法不喜欢在数组参数中包含“未定义”。

此外,如果我的代码看起来丑陋/烦人并且让您感到畏缩,那么请借此机会发泄..帮助我学习编写不会惹恼人们的代码;)

<小时/>

** 找到解决方案 ** 感谢您提醒我排序方法!(函数?)这就是我最终得到的结果:

function SecondGreatLow (arr) {
    var secondLow = 0,
        secondHigh = 0;
    arr.sort(function(a,b){
        return a-b;
    });
    for (var i = 1; i < arr.length; i++) {
        if (arr[i] !== arr[i-1]) {
            secondLow = arr[i];
            break;
        }
    }
    for (var j = (arr.length-2); j >= 0; j--) {
        if (arr[j] !== arr[j+1]) {
            secondHigh = arr[j];
            break;
        }
    }
    return secondLow + " " + secondHigh;
}
console.log(SecondGreatLow([1,1,2,2,3,3,4,4,5,5]));

多么棒的社区啊..我会带着更多问题回来,希望我有足够的信心在不久的将来回答一些问题。谢谢!

最佳答案

我觉得也许我错过了一些东西,但挑战似乎并不包括从原始数组中删除项目的要求,所以我不明白你为什么要以这种方式修改它。您提供的要求只是返回“a b”,其中 a 是第二低的,b 是第二高的。

所以,我首先建议对列表进行排序。由于您知道自己正在处理上限和下限,因此您不必迭代任何内容(也不应该)。您的测试数组已经排序,但确保顺序将使您的代码更加健壮并能够处理其他输入。查看Arrays API了解更多详情。

虽然看起来这可能超出了您的问题范围,但您可能还想研究排序算法以了解更多有关其工作原理的信息,而不是仅仅依赖 API。

排序后,您应该能够轻松地从边界向内进行比较,以获得第二低值和第二高值。

此外,您不需要使用 Math API,简单的不等运算符就可以解决问题(< 和 >)。

编辑:虽然我建议您自己解决该问题,但这里有一个简单的解决方案。我将其放在这里,以便如果您遇到困难,可以引用此内容(以及相关评论)以获取指导。

function SecondGreatLow(arr) {
  var i;
  var j;
  var lowest;
  var highest;
  var secondLowest;
  var secondHighest;

  //Sort Array
  arr.sort(function (a, b) {
    return a - b;
  });

  //Get Bounds
  //Since we sorted the array, and the default sort is in 
  //ascending lexicographical order, then we're guaranteed that 
  //our 'lowest' value is at index 0 and our 'highest' value is
  //at index arr.length -1.  Note that these values may be
  //equal.
  lowest = arr[0];
  highest = arr[arr.length - 1];

  //Search for second lowest.
  for (i = 0; i < arr.length; i++) {
    if (arr[i] > lowest) {
      secondLowest = arr[i];
      break;
    }
  }

  //If we reach the end of the array, but didn't 
  //find a greater value, then, since the array is sorted,
  //we're guaranteed that all values in the array are equal.
  //Therefore, the required value comparisons have no meaning,
  //and we return 'undefined'.
  if (secondLowest === 'undefined') {
    return 'undefined';    
  }

  //Search for second highest, working backwards from the 
  //high end of the array until we reach our crossover point 
  //with the previous search.  Either some value > arr[i] is the
  //second highest, or arr[i] is, so there's no point in looking 
  //at values in the indices lower than i.
  for (j = arr.length - 1; j >= i; j--) {
    if (arr[j] < highest) {
      secondHighest = arr[j];
      break;
    }
  }

  return secondLowest + ' ' + secondHighest;

}

var result = SecondGreatLow([3,3,4,5,4,6]);
console.log(result);

JSFiddle

关于javascript - 是否有 for 循环或 .forEach 方法删除当前数组元素,然后让流程从同一索引继续?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29597650/

相关文章:

javascript - 为什么我会收到 self.description(...) is undefined ?

javascript - 如何在 typescript 中解构枚举值?

arrays - VBA - 使用 For Each 语句更新数组中的值

javascript - innerHTML 为空? JS 表单验证

C# - For vs Foreach - 巨大的性能差异

vba - For Each 循环 : Some items get skipped when looping through Outlook mailbox to delete items

python - np.mean 对于跨多列具有特定值的行

javascript - 更改数组中每个项目的属性?

在 foreach 循环中使用 array_combine 时 PHP 内存耗尽

javascript - html 5 Canvas 绘图错误