负索引如何与`Array#[] =`一起使用?

时间:2013-02-24 07:48:57

标签: ruby arrays

我试着看看Array#[]=是如何运作的,然后玩了:

enum[int] = obj → obj
enum[start, length] = obj → obj
enum[range] = obj → obj

问题1

我有一个数组b在其nil索引处持有0

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

我尝试在下面的代码中将nil替换为整数10

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

为什么上面的代码不起作用,但下面的代码呢?对于大小为1的数组,为什么索引0-1的处理方式不同?

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

问题2

我创建了一个大小为2的数组,并执行了以下操作:

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

我认为负面索引永远不会增加数组的大小,但我不知道为什么。为什么下面的代码成功了?

a[-2..-3] = [3,4] #=> [3, 4]

3 个答案:

答案 0 :(得分:7)

我建议你看看Array documentation中的第一段。令人惊讶地说:“假设负索引相对于数组的末尾 - 也就是说,索引-1表示数组的最后一个元素,-2是数组中最后一个元素的下一个元素,因此上“。

这意味着,您可以a[-N]设置|N| <= a.size元素。a = [1,2] ; a[-3] = 3。这就是a[INBOUNDS_IDX..NONSENSE_IDX]=SMTH失败(3&gt; 2)的原因。

另一方面,[可能]没有记录红宝石阵列的功能:SMTH插入 INBOUNDS_IDX {{1索引:

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

这里的废话意味着“少于INBOUNDS_IDX,不能作为否定表示法中的索引处理”(这就是为什么上面示例中的a[2..-1]被视为a[2..(a.size - 1)]。)

答案 1 :(得分:0)

观察#1

-1索引与最后一个元素相关,如果数组没有size [],则在使用一个或多个元素初始化之前不能使用它。

观察#2:

是的,你是对的,负数索引永远不会增加数组的大小,如果只引用数组中的具体现有位置。不要认为数组是循环的(0索引符合N-1索引),所以你不能使用任何负面索引认为它是有效的

答案 2 :(得分:0)

<强> Q1:

空数组有0个元素,因此当您尝试使用负索引-1设置其元素0时,它将给出错误。 因为负数索引从数组开始循环。

所以 <{1}}使得无法

a)将元素放在最后位置,因为它为null

b)设定其值。因为它从未被捕获过。

a = []; a[-1] = 3将起作用,因为您告诉编译器

a)抓住第一个元素,

b)如果不存在则创建一个,然后将其分配给您请求的值。

请参阅official api doc特别提到正索引可以增长大小,负数索引超过数组的开头会引发错误。

<强> Q2:

以上解释几乎也回答了第二个问题。

给定a[0] = 5

a = [1,2]导致第一个休息点。您正尝试从末尾访问第3个元素,该元素不存在。按设计它会崩溃。

虽然a[-3] = 3在定义的数组的捕获范围内。

你要求解释器捕获最后一个元素(在这种情况下是从前面开始的第一个元素),并尝试调用一个范围,要求它增加数组的大小,并用你要求的任何东西填充它。 / p>

令人高兴的是,一切仍然很好,并且符合要求。很高兴知道。