How to access array in circular manner in JavaScript
Solution 1
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(","));
Solution 2
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:
- https://www.khanacademy.org/computing/computer-science/cryptography/modarithmetic/a/what-is-modular-arithmetic
- https://en.wikipedia.org/wiki/Modular_arithmetic
- https://en.wikipedia.org/wiki/Modulo_operation
- https://dev.to/maurobringolf/a-neat-trick-to-compute-modulo-of-negative-numbers-111e
Solution 3
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('****')
}
Solution 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(','));
}
Solution 5
how about this one-liner I made ?
var nextItem = (list.indexOf(currentItem) < list.length - 1)
? list[list.indexOf(currentItem) + 1] : list[0];
Anshul
Hello, I am Anshul from Bengaluru, India, currently working @ Navi.
Updated on February 23, 2021Comments
-
Anshul about 3 years
I have an array like
[A,B,C,D]
. I want to access that array within a for loop like asvar 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 }
I want to access that like in JavaScript, any ideas?
-
João Ramires almost 4 yearsDo you think Circular List is a way to solve this question? stackoverflow.com/questions/62238342/…
-
allez l'OM almost 4 years@JoãoRamires You should use getTime/setTime for your own question. See my answer there stackoverflow.com/questions/62238342/…
-
Garrett about 3 yearsOK. But this does not provide a wrap around slice of the source array. It also fails with negative numbers; e.g.
[1,2,3]
start = 1
,` len = -3` =>[2,1,3]
. -
wwgoncalves about 3 yearsI don't get it. (Negative number as array length?) Could you rephrase what you are trying to point out?
-
Mkdgs about 3 yearsWhy not just
let val = arr[Math.abs(i % n)];
? -
wwgoncalves about 3 yearsUnfortunately that won't work for negative values of
i
. The result -- remainder of the division -- will be different from the result expected from modular arithmetic. For example in JS(-1 % 10 + 10) % 10
evaluates to9
, butMath.abs(-1 % 10)
evaluates to1
. -
Garrett about 3 yearsThat approach creates an array for each shift. What if there was a function like slice that wraps around and takes a length, e.g.
array.cirSlice(start, len)
.[1,3,4].cirSlice(3,5)
results[4,1,3,4,1]
?