2009-07-19 58 views
4

在Perl中,數組的索引-1意味着最後一個元素:爲什麼我不能寫@F [1 ..- 1]來獲取元素1..last?

@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中的所有元素到最後一個元素,否?

回答

19

你的問題是@a[b..c]語法涉及兩個不同的操作。首先對b..c進行評估,返回一個列表,然後使用該列表對@a[]進行評估。範圍運算符..不知道它用於數組下標,所以就它而言,1和-1之間沒有任何內容。它返回空列表,所以數組返回一個空片。

+0

我明白了,那太糟糕了。我認爲Perl維護者應該仍然把它作爲一個特例來工作。 – Frank 2009-07-19 17:25:17

+4

它不需要特殊情況,因爲它已經非常簡單:$ a [1 .. $#a]。在下標括號中,使事情以不同的方式工作是沒有意義的。 – 2009-07-19 17:42:08

0

[]運算符將接受單個索引或範圍。

-1被接受爲索引以表示最後一個元素的索引。正確的方法是$#F。

1 ..- 1的範圍是空的,這就是爲什麼它不返回任何內容,因爲範圍評估與索引的評估是分開的。

+1

沒有[]運算符。它只是指標周圍的括號。它對他們沒有任何幫助。它只接受一個列表。它不關心你如何列表。 – 2009-07-19 17:40:18

8

沒有什麼特別的..在數組切片;它只是生成請求的範圍,然後查找該範圍的切片。

@a[-3..-1]所以=>@a[-3,-2,-1],並@a[1..3] =>@a[1,2,3],但@a[1..-1]變得@a[()]

4

$#F是F的最後一個有效索引,而不是元素的數量。

@F =(1,2,3); #所以$#樓爲2

5
print join ', ', 1..$#F; # 1, 2, 3, 4, 5, 6, ... 
print join ', ', 1..-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 

注:這是一個不完整的例子,它不會正確地對一些邊緣情況下工作

2

規則是:

  • 如果數組索引是n上 - 負(或,等價地,大於$[更大),啓動在陣列的開頭開始計數
  • 如果是否定的,如果給定的範圍內開始在端
  • 計數,返回數組切片

現在,就像(a,b)爲空,如果a> b,則集合1 .. -1也是空的。因此,

@a[ empty set ] 

對應於一個空的數組切片。