【问题标题】:Possible strange output of javascript forEach loopjavascript forEach 循环的可能奇怪输出
【发布时间】:2016-03-07 00:52:11
【问题描述】:

这个输出有什么意义?也许我想错了,但它应该是 dong 似乎相当具有描述性

var dataset = [1, 2, 3];

dataset.forEach(function(element, index, array) {
    //          (index, how many to remove)
    array.splice(0, 0);
});

returns [1,2,3] as expected

dataset.forEach(function(element, index, array) {
    array.splice(0, 3);
});

returns [] as expected

dataset.forEach(function(element, index, array) {
   array.splice(0, 1);
});

returns [3]

dataset.forEach(function(element, index, array) {
    array.splice(0, 2);
});

returns [3]

这让我质疑我对一切的理解,哈哈。我有一个更复杂的要求,其中一个对象数组可能具有属性“element.archived”

var dataset = [Object, Object, Object]

dataset.forEach(function(element, index, array) {
   if (element.archived) array.splice(index, 1);
});

我正在尝试遍历数组,并删除所有具有此属性值为 true 的对象。

【问题讨论】:

  • 我认为您只是使用了错误的工具进行过滤。看来你需要简单的array.filter
  • 你为什么在array.splice inside forEach?您真的需要在阵列上运行splice 3 次吗?
  • @RocketHazmat,正是我的问题是什么。 OP,您似乎对how splice works有误解。
  • splice 修改索引,forEach0 开始并向上计数。当它到达未定义的索引时,它会停止。因为长度改变了,所以未定义的索引更早。因此forEach 的调用次数少于初始长度
  • @JasonMacAnLighiche:不要不要将您的解决方案编辑到问题中。这个问题应该是一个question。你应该做的是接受正确的答案。

标签: javascript foreach iteration


【解决方案1】:

所以您想从具有archived: true 的数组中删除对象。这里有几种方法可以做到这一点:

您可以使用filter,它返回一个过滤数组:

var arr = dataset.filter(function (el) {
  return el.archived !== true;
});

或者您可以使用splice 在迭代元素时删除它们:

for (var i = dataset.length - 1; i >= 0; i--) {
  if (dataset[i].archived === true) dataset.splice(i, 1);
}

DEMO

【讨论】:

  • 似乎带有 splice 错误的示例 - 当我们删除项目时,我们不应该增加 i 变量
  • 多哈。感谢您的提醒。
  • @Andy 而不是为每个匹配减少 i 或“不增加”它,实际上向下循环更容易,因为这些索引不会更改 var i = dataset.length; while (i-- > 0) {...}
  • @PaulS.,谢谢。有时你重复代码足够多次它会成为习惯,并且在有人指出之前永远不会认为可能有更好的编写方式
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-15
  • 1970-01-01
  • 2012-07-11
  • 2020-07-12
  • 2015-06-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多