- Home /
getting element i+x from an array, looping through it
So, lets say I've got an array(a builtin array, but that doesn't really matter for the question) and I want to assign some values to the gameobjects in them.
I get these values from another array, but the numbers may be shifted by x amount. So to assign the right values to the right objects I would need to shift the element I get by using something along the lines of:
array[i+x] = value[i];
Obviously doing something like this will leave the first x elements in array empty, and gives an index out of range on the last x elements.
What I need to do to fix this is to check if i+x is higher than the length of array, and if so i should be 0. I think.
Is there any elegant way of doing this?
why would you want empty elements at the start of the array?
array[i + x < array.Length ? i + x : 0]
If you want it to loop around, use
array[(i + x) % array.Length]
Adding to the previous comment, I also think what you are doing would create a technical debt you will find yourself paying again and again in bugs and maintenance. If the arrays should be parallel, then make sure their indexes align, if not, dont use arrays where possible - switch to lists or some other collection.
If you find yourself in need of help in regards to simple arrays, this should be a hint that there must be an easier way.
First of all, I don't want empty elements, I was trying to say, if I'd iterate through the array with a normal for loop, I'd start with i=0, but x will increase, meaning the for loop would skip the first x elements in the array. Also, I'm not entirely sure what the ? and : do in that piece of code, could you explain?
Second, the problem is that the second array is actually parallel to the first normally, but the values assigned to the first array should be shifted by x in a lot of cases. $$anonymous$$ight be easier to explain using a little image:
? : is a shorthand for if else. a ? b : c
is the same as if( a ) then b; else c;
Answer by Hoeloe · Sep 05, 2013 at 08:19 AM
Sounds like what you want is the modulus function: %
. This takes the first value, and returns the remainder when divided by the second value, so, for example, 10%6
will give 4
. I assume you want to wrap the elements round, so the last x values becomes the first x values, in which case this is the perfect solution - you simply use the same code, but taking the modulus of the length! So, instead of using array[i+x]
, you'd use array[(i+x)%array.Length]
. This ensures that the value can never be equal to or greater than the length of the array, and if the given value (i+x) is, then it will wrap around, meaning that if i+x is equal to the array length, it will index into the array at 0, and if it is one greater than the array length, it will index in at 1, etc.
Had some trouble wrapping my head around this, and ended up using a bit of a roundabout way to do the same thing. this works flawlessly tho. So kudos to both you and syclamoth, as his comment seems to use pretty much the same method. Thanks!
It might be worth adding the length of the array before perfor$$anonymous$$g the %
function, this will allow the array to also cycle in reverse. I use something similar using an integer direction
of either 1 or 0 to cycle through elements bidirectionally. I believe the snippet blow may not work as intended if x
is less than -array.Length
.
var a = array[(i + x + array.Length) % array.Length]
You are right. The original code doesn't work as soon as x is less than 0. That's because the modulo operator in most program$$anonymous$$g languages do not work as the mathematical modulo. It preserves the sign so negative numbers will result in a negative result. So if the offset is say -3
you would get -3, -2 and -1 for the first 3 values (assu$$anonymous$$g i goes from 0 upwards). By adding one full range it all shifts into the positive range.
Though If you need a negative offset you can also just wrap the offset properly into the positive range. That would be the more secure way I guess. To get the modulo working for all negative numbers you would have to do this:
((i + x)%array.Length + array.Length) % array.Length
which looks crazy but always works.
(i + x)%array.Length
always returns a value in the range -length+1 to length-1. Adding the length will always make the number positive. The second modulo will ensure to get the right result for positive numbers.
Your answer
Follow this Question
Related Questions
Array strings/Loops problem 2 Answers
Iterate through Generic Dictionary? 3 Answers
iterate through array of objects with lists of objects 0 Answers