How does a negative index work with `Array # [] =`?

I tried to see how Array#[]= works, and played around:

 enum[int] = obj β†’ obj enum[start, length] = obj β†’ obj enum[range] = obj β†’ obj 

Question 1

I have one array b containing nil at its index 0 .

 b = [] b[0] # => nil 

I tried replacing nil integer 10 in the code below.

 b[-1] = 10 # => IndexError: index -1 too small for array; minimum: 0 

Why does this code not work, but the ones below? In the case of an array with size 1 , why are indexes 0 and -1 handled differently?

 b[0] = 5 # => 5 b[-1] = 10 # => 10 

Question 2

I created an array of size 2 and did the following:

 a = [1,2] a[-3] = 3 # => IndexError: index -3 too small for array; minimum: -2 a[-3] = [3] # => IndexError: index -3 too small for array; minimum: -2 a[-3..-4] = [3] # => RangeError: -3..-4 out of range 

I believe that a negative index never increases the size of the array, but I don't know why. Why was the code successful?

 a[-2..-3] = [3,4] #=> [3, 4] 
+4
source share
3 answers

I would suggest you take a look at the first paragraph in Array Documentation . This surprisingly says: "A negative index is considered relative to the end of the array, ie Index -1 indicates the last element of the array, -2 is the next after the last element in the array, and therefore on."

This means that you can set the a[-N] th element if and only |N| <= a.size |N| <= a.size . That is why a = [1,2] ; a[-3] = 3 a = [1,2] ; a[-3] = 3 fails (3> 2).

On the other hand, there is a [probably] undocumented function for ruby ​​arrays: a[INBOUNDS_IDX..NONSENSE_IDX]=SMTH will insert SMTH before the INBOUNDS_IDX index:

 a=[1,2] a[2..0]='a' a[2..1]='b' a[2..-100]='c' # β‡’ [1, 2, "c", "b", "a"] a[2..-1]='q' # β‡’ [1, 2, "q"] 

The imperfection here means "less than INBOUNDS_IDX, and is not treated as an index in negative notation" (which is why a[2..-1] in the above example is considered as a[2..(a.size - 1)] .)

+6
source

Observation # 1

The -1 index is associated with the last element, yo, if the array does not have size [], you cannot use it until you initialize it with one or more elements.

Observation No. 2:

Yes, you are right, a negative index never increases the size of the array if it refers only to a specific existing position in the array. Do not think that the array is circular (index 0 is associated with index N-1), so you cannot use a negative index considering it valid.

0
source

Q1:

An empty array has 0 elements, so when you try to set its element to 0 with a negative index of -1 it will throw an error. Since a negative index cycles through the array from the end.

So, a = []; a[-1] = 3 a = []; a[-1] = 3 makes it impossible

a) get the element in the last position, since its null

b) set its value. since he was never captured.

a[0] = 5 will work because you tell the compiler

a) take the first element,

b) create one, if not, and then assign that value that you requested.

See the official api doc for a positive index, size may increase, a negative index preceding the beginning of the array causes an error.

Q2:

The above explanation almost also answers the second question.

Given a = [1,2]

a[-3] = 3 causes the first break point. You are trying to access the third element from an end that does not exist. By design, it breaks.

While a[-2..-3] is in the capture range of a specific array.

You ask the interpreter to grab the second element from the last (the first in this case in this case) and try to call a range that asks it to increase the size of the array and fill it with what you requested.

Fortunately, everything is still good and at will. Good to know.

0
source

All Articles