【问题标题】:Trying to understand the for loop in this JavaScript duplicate removing algorithm试图理解这个 JavaScript 重复删除算法中的 for 循环
【发布时间】:2019-10-07 23:51:53
【问题描述】:

首先,这是算法:

var removeDuplicates = function(nums) {
    for (var i = 0; i < nums.length;) {
        if (nums[i] === nums[i + 1]) {
            nums.splice(i, 1)
        }
        else i++
    }
    return nums
};

它接受一个排序的数字数组并删除所有重复项以返回修改为仅包含唯一数字的原始数组。

我的问题主要是关于 for 循环的使用。在这个 for 循环中,我们省略了第三条语句,而是在 else 条件中递增 i

如果满足if 条件,循环如何知道检查nums 的下一个索引? IE。如果我们从未点击过else,那么i 是如何增加的?它甚至增加了吗?我知道这可能与我们在 if 条件下拼接(因此缩短)nums 数组的事实有关,但我很难完全理解为什么一旦 if 语句完成一次,循环就不会结束.

【问题讨论】:

  • splice 改变长度

标签: javascript arrays algorithm


【解决方案1】:

当你这样做时

nums.splice(i, 1)

这会从索引i 处的数组中删除一项。比如i为2,当前数组为

[0, 1, 2, 2, 3, 4]

那么,在splice 发生之后,数组就变成了

[0, 1, 2, 2, 3, 4]
       ^^ REMOVED: Array mutates to
[0, 1, 2, 3, 4]

以前位于索引i + 1 的项目现在位于索引i,因此for 循环的下一次迭代不应增加i

如果您确实增加了i,那么紧随已删除项目之后的每个项目都将被跳过,并且根本不会迭代:

var removeDuplicates = function(nums) {
    for (var i = 0; i < nums.length; i++) {
        if (nums[i] === nums[i + 1]) {
            nums.splice(i, 1)
        }
    }
    return nums
};

console.log(removeDuplicates([0, 1, 1, 1]));

不过,这种代码风格还是非常令人困惑:当一个对象发生变化时在你迭代它的同时,它可能很不清楚正在实现的逻辑完成了什么。最好通过 Set 去重:

var removeDuplicates = nums => [...new Set(nums)];

console.log(removeDuplicates([0, 1, 1, 1]));

【讨论】:

  • 我明白了,非常感谢您的回复。那么我们是否在拼接之后“留在”for 循环中直到 i
  • 是的,无论i或数组长度发生怎样的变化,循环都会一直持续到条件i &lt; nums.length为假;每次迭代开始时都会重新检查该条件。
  • 完成!本来打算昨晚做的,但它说我必须等待一段时间才能这样做。再次感谢!
猜你喜欢
  • 2018-08-14
  • 1970-01-01
  • 2013-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-03
  • 2019-03-14
  • 2023-01-25
相关资源
最近更新 更多