在Perl中,数组索引-1
表示最后一个元素:
@F=(1,2,3);
print $F[-1]; # result: 3
您也可以使用$#
表示法,$#F
:
@F=(1,2,3);
print $F[$#F]; # result: 3
那么,当我想指定范围中的最后一个元素时,-1
和$#F
为什么不给出相同的结果:
print @F[1..$#F]; # 23
print @F[1..-1]; # <empty>
数组@F[1..-1]
应该包含从元素1
到最后一个元素的所有元素,不是吗?
答案 0 :(得分:19)
您的问题是@a[b..c]
语法涉及两个不同的操作。首先评估b..c
,返回一个列表,然后使用该列表评估@a[]
。范围运算符..
不知道它被用于数组下标,所以就它而言,1和-1之间没有任何内容。它返回空列表,因此数组返回一个空切片。
答案 1 :(得分:8)
在数组切片中没有什么特别的东西;它只是生成请求的范围,然后查找该范围的切片。
所以@a[-3..-1]
=&gt; @a[-3,-2,-1]
和@a[1..3]
=&gt; @a[1,2,3]
,但@a[1..-1]
变为@a[()]
。
答案 2 :(得分:5)
print join ', ', 1..$#F; # 1, 2, 3, 4, 5, 6, ...
print join ', ', 1..-1; #
原因是'..
'运算符在数组下标中没有做任何特殊操作。
在列表上下文中,它返回从左值到右值计数(向上)的值列表。如果左侧值大于正确值,则返回空列表。
$#F
是最后一个元素的索引,与长度减去一个“@F -1
”相同。 (如果长度至少为一个。)
$F[-1]
只是一种特殊情况,可以更方便地从另一端获取元素,而无需手动计算位置。
$F[-1] === $F[ @F -1 ] === $F[ $#F ]
@F[ 1 .. (@F -1) ] === @F[ 1 .. $#F ]
@F[ 1 .. (@F -2) ] === @F[ 1 .. ( $#F -1 ) ]
了解这一点,您可以在范围运算符中使用变量:
use strict;
use warnings;
use feature 'say';
sub list{
my($arr,$first,$last) = @_;
$first = @$arr + $first if $first < 0;
$last = @$arr + $last if $last < 0;
return @$arr[ $first .. $last ];
}
my @F = 1..3;
say join ', ', list(\@F,1,-1)
2, 3
注意:这是一个不完整的示例,对于某些边缘情况它将无法正常工作
答案 3 :(得分:4)
$#F是F的最后一个有效索引,而不是元素的数量。
@F =(1,2,3); #so $#F是2
答案 4 :(得分:2)
规则是:
$[
),则从数组的开头开始计数现在,就像(a,b)一样,如果 a&gt; b ,集合1 .. -1
也是空的。因此,
@a[ empty set ]
对应于一个空数组切片。
答案 5 :(得分:0)
[]运算符将接受单个索引或范围。
-1被接受为索引,表示最后一个元素的索引。正确的方法是$#F。
1 ..- 1的范围是空的,这就是为什么它不返回任何内容,因为范围评估与索引的评估是分开的。