JavaScript 循环问题

2020-11-28 14:45:57 +08:00
 sudoy

JavaScript 循环好像哪里不对,哪位老哥帮看下。

price = ['apple', 10, 'orange', 6, 'apple', 10, 'apple', 10, 'banana', 5];

for (i=0; i<price.length; i++) {
  if (price[i] == 'apple') {
    pair = price.splice(i, 2);
    console.log(i, pair);
    console.log(price);
  };
};

期望得到的结果是:

0 ["apple", 10]
["orange", 6, "apple", 10, "apple", 10, "banana", 5]
2 ["apple", 10]
["orange", 6, "apple", 10, "banana", 5]
2
["orange", 6, "banana", 5]

运行当前代码得到的结果是:

0 ["apple", 10]
["orange", 6, "apple", 10, "apple", 10, "banana", 5]
2 ["apple", 10]
["orange", 6, "apple", 10, "banana", 5]
2176 次点击
所在节点    问与答
21 条回复
noe132
2020-11-28 14:55:17 +08:00
边循环边改数组是大忌。
des
2020-11-28 14:59:27 +08:00
不要在循环中修改数组!不要在循环中修改数组!不要在循环中修改数组!
sudoy
2020-11-28 15:00:19 +08:00
@noe132 嗯,index 好像出问题了。不过我需要做到一旦匹配到就要移除掉,避免重复匹配。所以不得不从数组里面移除掉
sugarsalt
2020-11-28 15:07:22 +08:00
0 ["apple", 10]
["orange", 6, "apple", 10, "apple", 10, "banana", 5]
2 ["apple", 10]
["orange", 6, "apple", 10, "banana", 5]
此时 i 已经等于 2 了,再++就是 3,自然找不到 apple 了
hoyixi
2020-11-28 15:08:26 +08:00
filter 一下,返回一个新数组好了,有 JS 内置实现
luob
2020-11-28 15:08:35 +08:00
你这不都找到原因了吗……
aaronlam
2020-11-28 15:12:34 +08:00
实在不济,你在外面搞个新数组,不就好了。。
zackwan95
2020-11-28 15:19:08 +08:00
都 ES2020 了,用 array 内置的 api 吧,这玩意用 reduce 正合适
Caballarii
2020-11-28 16:18:13 +08:00
从右向左循环就 ok 了
xiangyuecn
2020-11-28 16:22:52 +08:00
这玩意跟语言无关, 什么 filter ES2020 “不要在循环中修改数组”,没有一毛钱关系
TommyDx
2020-11-28 16:29:34 +08:00
两边一起减,少了循环次数
sudoy
2020-11-28 17:59:14 +08:00
谢谢大家回复,已经找到解决办法了:就是搞个新的数组
ddsfeng
2020-11-28 18:08:59 +08:00
倒序遍历 可解.
sudoy
2020-11-28 23:43:51 +08:00
@ddsfeng 攒👍
chenyu8674
2020-11-28 23:59:21 +08:00
price = ['apple', 10, 'orange', 6, 'apple', 10, 'apple', 10, 'banana', 5];

for (i=0; i<price.length; i++) {
if (price[i] == 'apple') {
pair = price.splice(i, 2);
i -= 2;
};
};
chenyu8674
2020-11-29 00:03:07 +08:00
@chenyu8674 #15 困脑抽了,i--就行
lbyo
2020-11-29 00:47:22 +08:00
@chenyu8674 #16
不光需要 i--

```
let price = ['apple', 10, 'orange', 6, 'apple', 10, 'apple', 10, 'banana', 5];

for (i = price.length - 1; i >= 0; i--) {
if (price[i] == 'apple') {
pair = price.splice(i, 2);
console.log(i, pair);
console.log(price);
};
}
```
autoxbc
2020-11-29 03:54:34 +08:00
for (i = 0; i < price.length; ) {
  if (price[i] == 'apple') {
  ...
 } else {
   i++
 }
};

只需要把 for 句首的 i++ 转移到 else 分支里就够了
sudoy
2020-11-29 17:41:26 +08:00
@autoxbc 谢谢
pwn
2020-11-30 10:11:14 +08:00
不止 JavaScript,任何语言(大概)都是如此,price.length 是每次循环开始的时候会计算的,也就是说在修改了数组 price 之后,price.length 是会变的!会变的!
我通常是在循环体外面把这个值固定下来,let length = price.length,然后才开始循环。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/730109

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX