以下Groovy代码
lines = ['0','1','2','3','4','5']
println lines[1..lines.size()-1]
println lines[1..-1]
println lines[1..<lines.size()-1]
println lines[1..<-1]
println lines[1..<-2]
println lines[1..-2]
Run Code Online (Sandbox Code Playgroud)
产生这个输出:
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
[1, 2, 3, 4]
[1, 0]
[1, 2, 3, 4, 5]
[1, 2, 3, 4]
Run Code Online (Sandbox Code Playgroud)
由于-1是列表中最后一个元素的索引,前两个是有意义的(Groovy中的范围包括end元素,而不是像Java中的其他地方一样省略它:-()
第3行是所需的输出(没有第一个和最后一个元素的列表).
我很担心输出#4:为什么我得到[1, 0]的1..-1?
另外[1, 2, 3, 4, 5]对于范围1..<-2似乎是错误的.
为什么会这样?
epi*_*ian 18
在我看来,采用所有元素但最后一个元素的最佳方法是使用以下take方法:
def list = ['a', 'b', 'c']
assert list.take(list.size() - 1) == ['a', 'b']
Run Code Online (Sandbox Code Playgroud)
它在大小== 1的角落情况下表现正常:
def list = ['one']
assert list.take(list.size() - 1) == []
Run Code Online (Sandbox Code Playgroud)
虽然我更喜欢它在大小== 0的情况下抛出异常,但行为并不那么糟糕:
def list = []
assert list.take(list.size() - 1) == []
Run Code Online (Sandbox Code Playgroud)
你也可以使用list[0..<list.size()-1](你的第三个例子),除了空列表之外它会表现相同,在这种情况下它会抛出一个ArrayIndexOutOfBoundsException,但我认为它不像take对应物那样可读.
另一个可接受的解决方案是使用list[0..-2](你的最后一个例子),我觉得它看起来更优雅,但不幸的是,当尺寸== 1时,它会中断ArrayIndexOutOfBoundsException.
在您的示例中(我假设您打算使用0作为起始索引而不是1,如果您想包括除最后一个之外的所有元素):
lines[0..lines.size()-1]等同于lines[0..-1]因为getAt(Range)列表方法将使用与索引相同的方式处理具有负索引的范围getAt(Integer),即访问(list.size() + negativeIndex)列表的第th个元素.因此list[0..-1]与"从第一个元素到最后一个元素"的说法相同,它与复制列表相同; 并且list[-1..0]与"从最后到第一"相同,它相当于list.reverse():)
其他非包含范围示例的问题在于,在列表访问之前评估非包含范围,并且它们评估为不正确的包含范围.例如,0..<-2评估为0..-1,这就是它返回所有元素的原因.0..<-1求值为0..0,它只返回第一个元素.
请注意,空范围是一种特殊情况.它被表示为0..<0并且它没有包含等价物(因此Groovy不会在这里进行任何魔术转换).这就是为什么list[0..<list.size()-1]当size == 1(范围评估为空范围)时工作,而list[0..-2]不是:)
| 归档时间: |
|
| 查看次数: |
11663 次 |
| 最近记录: |