【问题标题】:How to access array in circular manner in JavaScript如何在 JavaScript 中以循环方式访问数组
【发布时间】:2013-07-03 05:14:28
【问题描述】:

我有一个类似[A,B,C,D] 的数组。我想在 for 循环中访问该数组,例如

var arr = [A,B,C,D];

var len = arr.len;
for(var i = 0;i<arr.len;i++){
    0 - A,B,C
    1 - B,C,D
    2 - C,D,A
    3 - D,A,B
}

我想像在 JavaScript 中一样访问它,有什么想法吗?

【问题讨论】:

    标签: javascript arrays loops circular-buffer


    【解决方案1】:

    回答主要问题,有人可以使用模算术以循环方式访问数组。这可以在 JavaScript 中使用模数运算符 (%) 和解决方法来实现。

    给定一个长度为n的数组arr和一个存储在其中的值val,将通过访问索引i获得,循环方式,更安全的方式,访问数组,忽略i 的值和符号是:

    let val = arr[(i % n + n) % n];
    

    这个小技巧是必要的——有人不能直接使用取模结果——因为 JavaScript 总是将取模运算评估为被除数(第一个操作数)和除数(第二个操作数)之间除法的余数,而不考虑它们的符号但将除数的符号分配给余数。这种行为并不总是导致模算术的理想“环绕”效果,并可能导致对数组负位置的错误访问。

    更多信息参考:

    1. https://www.khanacademy.org/computing/computer-science/cryptography/modarithmetic/a/what-is-modular-arithmetic
    2. https://en.wikipedia.org/wiki/Modular_arithmetic
    3. https://en.wikipedia.org/wiki/Modulo_operation
    4. https://dev.to/maurobringolf/a-neat-trick-to-compute-modulo-of-negative-numbers-111e

    【讨论】:

    • 好的。但这并没有提供源数组的切片。它也因负数而失败;例如[1,2,3]start = 1,`len = -3` => [2,1,3].
    • 我不明白。 (作为数组长度的负数?)你能改写你要指出的内容吗?
    • 为什么不直接let val = arr[Math.abs(i % n)];
    • 不幸的是,这不适用于i 的负值。结果——除法的余数——将不同于模运算的预期结果。例如,在 JS 中,(-1 % 10 + 10) % 10 的计算结果为 9,但 Math.abs(-1 % 10) 的计算结果为 1
    【解决方案2】:

    试试这个:

    var arr = ["A","B","C","D"];
    for (var i=0, len=arr.length; i<len; i++) {
        alert(arr.slice(0, 3).join(","));
        arr.push(arr.shift());
    }
    

    如果不改变数组,它将是

    for (var i=0, len=arr.length; i<len; i++) {
        var str = arr[i];
        for (var j=1; j<3; j++)
            str += ","+arr[(i+j)%len]; // you could push to an array as well
        alert(str);
    }
    // or
    for (var i=0, len=arr.length; i<len; i++)
        alert(arr.slice(i, i+3).concat(arr.slice(0, Math.max(i+3-len, 0)).join(","));
    

    【讨论】:

      【解决方案3】:

      只需使用模数运算符,您就可以循环访问数组。

      var arr = ['A', 'B', 'C', 'D'];
      
      for (var i = 0, len = arr.length; i < len; i++) {
        for (var j = 0; j < 3; j++) {
          console.log(arr[(i + j) % len])
        }
        console.log('****')
      }

      【讨论】:

        【解决方案4】:
        for (var i = 0; i < arr.length; i++) {
            var subarr = [];
            for (var j = 0; j < 3; j++) {
                subarr.push(arr[(i+j) % arr.length]);
            }
            console.log(i + " - " + subarr.join(','));
        }
        

        【讨论】:

          【解决方案5】:

          我做的这个单线怎么样?

          var nextItem = (list.indexOf(currentItem) < list.length - 1)
                                  ? list[list.indexOf(currentItem) + 1] : list[0];
          

          【讨论】:

            【解决方案6】:

            “就地”循环移位的一条线解决方案:

            const arr = ["A","B","C","D"];
            arr.forEach((x,i,t) => {console.log(i,t); t.push(t.shift());});
            console.log("end of cycle", arr); // control: cycled back to the original
            

            日志:

            0 Array ["A", "B", "C", "D"]
            1 Array ["B", "C", "D", "A"]
            2 Array ["C", "D", "A", "B"]
            3 Array ["D", "A", "B", "C"]
            "end of cycle" Array ["A", "B", "C", "D"]
            

            如果您只想要前 3 项,请使用:

            arr.forEach((x,i,t) => {console.log(i,t.slice(0, 3)); t.push(t.shift());});
            

            【讨论】:

            • 你认为循环列表是解决这个问题的一种方法吗? stackoverflow.com/questions/62238342/…
            • @JoãoRamires 您应该使用 getTime/setTime 来解决您自己的问题。在那里查看我的答案stackoverflow.com/questions/62238342/…
            • 这种方法为每个班次创建一个数组。如果有一个像 slice 这样的函数会环绕并占用一定的长度,例如array.cirSlice(start, len)[1,3,4].cirSlice(3,5) 结果[4,1,3,4,1]?
            【解决方案7】:

            另一种解决方案:

                var arr = ['A','B','C','D'];
                var nextVal = function (arr) {        
                    return arr[( ( ( nextVal.counter < ( arr.length - 1 ) ) ? ++nextVal.counter : nextVal.counter=0  )   )];
                };
            
                for(var i=0;i<arr.length;i++){
                    console.log(nextVal(arr)+','+nextVal(arr)+','+nextVal(arr));
                }

            并且基于模数:

            var arr = ['A','B','C','D'];
            var len = arr.length;
            
            var nextVal = function (arr, dir = 1) { 
                    if ( dir < 0 ) { nextVal.counter--;}
                    let i = (nextVal.counter % len + len) % len;  
                    if ( dir > 0 ) { nextVal.counter++; }
                    return arr[i];
            };
            
            nextVal.counter=0;
            for(var i=0;i<arr.length;i++){
                console.log(nextVal(arr)+','+nextVal(arr)+','+nextVal(arr));
            }
            
            // in reverse 
            console.log('-------------------');
            nextVal.counter=0;
            for(var i=0; i<10; i++) {
                console.log(nextVal(arr, -1)+','+nextVal(arr, -1)+','+nextVal(arr, -1));
            }

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2017-10-22
              • 2015-08-30
              • 2015-11-15
              • 1970-01-01
              • 2021-03-27
              • 1970-01-01
              • 1970-01-01
              • 2018-08-08
              相关资源
              最近更新 更多