qw
?操作符使創(chuàng)建數(shù)組更容易。它意為將引用空白分成列表。
# Perl 5
my @stooges = qw( Larry Curly Moe Iggy );
# or
my @stooges = qw(
Larry
Curly
Moe
Iggy
);
在 Perl 6 中,qw
?更簡潔:
my @stooges = < Larry Curly Moe Iggy >;
# or
my @stooges = <
Larry
Curly
Moe
Iggy
>;
元素不做內(nèi)插:
my @array = qw( $100,000 ); # Perl 5
my @array = < $100,000 >; # Perl 6
@array
?的單一元素是“$100,000”。
要獲得數(shù)組的單個標量,使用?[]
?和?$
?印記。在 Perl 中所有數(shù)組都從 0 開始。
$stooges[1] # Curly
數(shù)組也能使用負偏移從尾端訪問。
$stooges[-1] # Iggy
讀取不存在的元素將得到?undef
。
$stooges[47] # undef
將數(shù)組放到標量環(huán)境能得到其長度。一些人也喜歡直接使用?scalar
。
my $stooge_count = scalar @stooges; # 4
my $stooge_count = @stooges; # 4
不要使用?length
?來獲得數(shù)組的長度。那只會得到字符串的長度。
my $moe_length = length $stooges[@stooges/2];
length $stooges[2];
length 'Moe';
3;
數(shù)組沒有任何有限的大小,且不必預(yù)先聲明。數(shù)組按需更改其大小。
數(shù)組也不稀疏。下列代碼創(chuàng)建 10,000 個元素的數(shù)組。
my @array = ();
$array[10000] = 'x';
@array?現(xiàn)在具有 10,001 個元素(0-10,000)。它只填入了一個,其他 10,000 個都是undef
。
不像 PHP,當數(shù)組合并時會平展開為一個大列表。
my @sandwich = ( 'PB', 'J' );
my @other_sandwich = ( 'B', 'L', 'T' );
my @ingredients = ( @other_sandwich, @sandwich );
# ( 'B', 'L', 'T', 'PB', 'J' )
這意味著你不能將一個數(shù)組包含到另一個數(shù)組或哈希中。那樣的話,你將需要使用引用。
Perl 最好的特性之一是在列表的尾端能帶一個擴展的逗號。例如:
my @array = (
'This thing',
'That thing',
);
當你編輯代碼時,這使添加或者刪除項目十分容易,因為你無需將最后一個項目作為特殊情況處理。
my @array = (
'This thing',
'That thing',
'The other thing',
);
shift
?從數(shù)組開頭移除元素。
my $next_customer = shift @customers;
unshift
?將元素添加到數(shù)組的開頭。
unshift @customers, $line_jumper;
push
?將元素添加到數(shù)組的結(jié)尾。
push @customers, $dio; # The last in line
pop
?從數(shù)組的結(jié)尾移除元素。
my $went_home = pop @customers;
數(shù)組分片只是使用多個索引訪問數(shù)組。
my @a = 'a'..'z'; # 26 letters
# a, e, i, o, u...
my @vowels = @a[0,4,8,14,20];
# And sometimes "y"
push( @vowels, $a[-2] ) if rand > .5;
注意:當訪問數(shù)組分片時,印記是?@
,不是?$
。因為你返回的是數(shù)組,而不是標量。新手常范的錯誤是使用?@
?印記而不是?$
?訪問一個數(shù)組元素。那將返回分片,實則是列表。
# WRONG: Returns a 1-element list, or 1 in scalar context
my $z = @a[-1];
# RIGHT: Returns a single scalar element
my $z = $a[-1];
你能夠?qū)?shù)組分片作為左值(lvalues),即能賦值給等號左邊的值。
# Replace vowels with uppercase versions
@a[0,4,8,14,20] = qw( A E I O U );
# Swap first and last elements
@a[0,-1] = @a[-1,0];
注意:分片的左邊和右邊大小必須相同。在等號右邊缺少的值將使用?undef
?換掉。
splice
?就地修改數(shù)組splice
?讓你拼接數(shù)組為另一個數(shù)組。讓我們來看幾個常見的錯誤做法,那應(yīng)該能說明它的有用性。
my @a = qw(Steve Stu Stan);
$a[1] = ['Stewart', 'Zane'];
# @a = ('Steve', ARRAY(0x841214c), 'Stan')
# Memory address to an array reference
my @a = qw(Steve Stu Stan);
my @b = qw(Stewart Zane);
$a[1] = @b;
# @a = ('Steve', 2, 'Stan')
# Returns a scalar reference, the length of @b
現(xiàn)在使用?splice
:
@a = qw(Steve Stu Stan);
splice @a, 1, 1, 'Stewart', 'Zane';
# @a = ('Steve', 'Stewart', 'Zane', 'Stan')
# This is just what we wanted
讓我們分解?splice
?的參數(shù)列表:首先,我們命名要操作的數(shù)組(@a); 其次,我們定義偏移(離我們想拼接的列表開始有多遠);第三,我們指定 拼接的長度;最后,我們列出想要插入的項目。
如果遇到錯誤,那么通過?perldoc -f splice
?來了解詳情。
map
?處理數(shù)組map
?本質(zhì)上是返回列表的?foreach
?循環(huán)。
你可以使用它將數(shù)組轉(zhuǎn)換成哈希:
my @array = ( 1, 2, 3, 4, 5 );
my %hash = map { $_ => $_ * 9 } @array;
# %hash = ( 1 => 9, 2 => 18, 3 => 27, 4 => 36, 5 => 45 )
或者變成列表:
my @array = ( 'ReD', 'bLue', 'GrEEN' );
my @fixed_array = map(ucfirst, map(lc, @array)); # note the nested 'map' functions
# @fixed_array = ( 'Red', 'Blue', 'Green' )
注意:如果你修改?$_
,源數(shù)據(jù)也會被修改。這樣,上例可以修改成:
my @array = ( 'ReD', 'bLue', 'GrEEN' );
map { $_ = ucfirst lc $_ } @array;
# @array = ( 'Red', 'Blue', 'Green' )
grep
?從數(shù)組選擇項目grep
?本質(zhì)上也是返回列表的?foreach
?循環(huán)。但它不像?map
,它只返回導(dǎo)致條件為真的元素。
my @array = ( 0, 1, 2, 3, 4, 5 );
my @new_array = grep { $_ * 9 } @array;
# @new_array = ( 1, 2, 3, 4, 5 );
它也將如?map
?一樣修改源數(shù)據(jù):
my @array = ( 0, 1, 2, 3, 4, 5 );
my @new_array = grep { $_ *= 9 } @array;
# @array = ( 0, 9, 18, 27, 36, 45 );
# @new_array = ( 9, 18, 27, 36, 45 );
我們也可以傳遞正則表達式給?grep
。在本例中,我們只想把包含?Doe?的人放到新數(shù)組:
my @people = (
'John Doe',
'Jane Doe',
'Joe Sixpack',
'John Q. Public',
);
my @does = grep { $_ =~ /\bDoe$/ } @people;
# @does = ('John Doe', 'Jane Doe');
或更短的:
my @does = grep { /\bDoe$/ } @people;
更多建議: