How to access array in circular manner in JavaScript

前端 未结 6 428
攒了一身酷
攒了一身酷 2020-12-05 08:40

I have an array like [A,B,C,D]. I want to access that array within a for loop like as

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

var len = arr.len;
for(var i = 0;i&         


        
相关标签:
6条回答
  • 2020-12-05 08:57

    Try this:

    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());
    }
    

    Without mutating the array, it would be

    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(","));
    
    0 讨论(0)
  • 2020-12-05 08:58

    Answering to the main question, someone can access an array in a circular manner using modular arithmetic. That can be achieved in JavaScript with the modulus operator (%) and a workaround.

    Given an array arr of a length n and a value val stored in it that will be obtained through an access index i, the circular manner, and safer way, to access the array, disregarding the value and sign of i, would be:

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

    This little trick is necessary -- someone can not use the modulus result straightforwardly -- because JavaScript always evaluates a modulus operation as the remainder of the division between dividend (the first operand) and divisor (the second operand) disconsidering their signs but assigning to the remainder the sign of the dividend. That behavior does not always result in the desired "wrap around" effect of the modular arithmetic and could result in a wrong access of a negative position of the array.

    References for more information:

    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
    0 讨论(0)
  • 2020-12-05 08:58

    One line solution for "in place" circular shift:

    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
    

    logs:

    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"]
    

    If you want only the first 3 items, use:

    arr.forEach((x,i,t) => {console.log(i,t.slice(0, 3)); t.push(t.shift());});
    
    0 讨论(0)
  • 2020-12-05 09:09

    Simply using modulus operator you can access array in circular manner.

    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('****')
    }

    0 讨论(0)
  • 2020-12-05 09:10

    how about this one-liner I made ?

    var nextItem = (list.indexOf(currentItem) < list.length - 1)
                            ? list[list.indexOf(currentItem) + 1] : list[0];
    
    0 讨论(0)
  • 2020-12-05 09:21
    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(','));
    }
    
    0 讨论(0)
提交回复
热议问题