为什么我不能写@F [1 ..- 1]来获取元素1..last?

时间:2009-07-19 15:47:08

标签: perl arrays syntax notation

在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到最后一个元素的所有元素,不是吗?

6 个答案:

答案 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的范围是空的,这就是为什么它不返回任何内容,因为范围评估与索引的评估是分开的。