V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
sudoy
V2EX  ›  问与答

JavaScript 循环问题

  •  
  •   sudoy · Nov 28, 2020 · 2977 views
    This topic created in 1990 days ago, the information mentioned may be changed or developed.

    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]
    
    21 replies    2020-11-30 14:37:00 +08:00
    noe132
        1
    noe132  
       Nov 28, 2020   ❤️ 1
    边循环边改数组是大忌。
    des
        2
    des  
       Nov 28, 2020   ❤️ 1
    不要在循环中修改数组!不要在循环中修改数组!不要在循环中修改数组!
    sudoy
        3
    sudoy  
    OP
       Nov 28, 2020
    @noe132 嗯,index 好像出问题了。不过我需要做到一旦匹配到就要移除掉,避免重复匹配。所以不得不从数组里面移除掉
    sugarsalt
        4
    sugarsalt  
       Nov 28, 2020   ❤️ 1
    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
        5
    hoyixi  
       Nov 28, 2020   ❤️ 1
    filter 一下,返回一个新数组好了,有 JS 内置实现
    luob
        6
    luob  
       Nov 28, 2020
    你这不都找到原因了吗……
    aaronlam
        7
    aaronlam  
       Nov 28, 2020 via iPhone
    实在不济,你在外面搞个新数组,不就好了。。
    bQ3u9RAQt4125PUK
        8
    bQ3u9RAQt4125PUK  
       Nov 28, 2020 via iPhone   ❤️ 1
    都 ES2020 了,用 array 内置的 api 吧,这玩意用 reduce 正合适
    Caballarii
        9
    Caballarii  
       Nov 28, 2020
    从右向左循环就 ok 了
    xiangyuecn
        10
    xiangyuecn  
       Nov 28, 2020
    这玩意跟语言无关, 什么 filter ES2020 “不要在循环中修改数组”,没有一毛钱关系
    TommyDx
        11
    TommyDx  
       Nov 28, 2020
    两边一起减,少了循环次数
    sudoy
        12
    sudoy  
    OP
       Nov 28, 2020 via iPhone
    谢谢大家回复,已经找到解决办法了:就是搞个新的数组
    xqin
        13
    xqin  
       Nov 28, 2020   ❤️ 2
    倒序遍历 可解.
    sudoy
        14
    sudoy  
    OP
       Nov 28, 2020
    @ddsfeng 攒👍
    chenyu8674
        15
    chenyu8674  
       Nov 28, 2020   ❤️ 1
    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
        16
    chenyu8674  
       Nov 29, 2020
    @chenyu8674 #15 困脑抽了,i--就行
    hive
        17
    hive  
       Nov 29, 2020   ❤️ 1
    @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
        18
    autoxbc  
       Nov 29, 2020   ❤️ 1
    for (i = 0; i < price.length; ) {
      if (price[i] == 'apple') {
      ...
     } else {
       i++
     }
    };

    只需要把 for 句首的 i++ 转移到 else 分支里就够了
    sudoy
        19
    sudoy  
    OP
       Nov 29, 2020 via iPhone
    @autoxbc 谢谢
    pwn
        20
    pwn  
       Nov 30, 2020   ❤️ 1
    不止 JavaScript,任何语言(大概)都是如此,price.length 是每次循环开始的时候会计算的,也就是说在修改了数组 price 之后,price.length 是会变的!会变的!
    我通常是在循环体外面把这个值固定下来,let length = price.length,然后才开始循环。
    sudoy
        21
    sudoy  
    OP
       Nov 30, 2020
    @autoxbc 我最后用了这个方法😍
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   5697 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 89ms · UTC 07:56 · PVG 15:56 · LAX 00:56 · JFK 03:56
    ♥ Do have faith in what you're doing.