數(shù)組

2018-02-24 16:03 更新

簡(jiǎn)單創(chuàng)建單詞數(shù)組

qw?操作符使創(chuàng)建數(shù)組更容易。它意為將引用空白分成列表。

# Perl 5
my @stooges = qw( Larry Curly Moe Iggy );
# or
my @stooges = qw(
    Larry
    Curly
    Moe
    Iggy
);

在 Perl 6 中,qw?更簡(jiǎn)潔:

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ù)字值訪問(wèn)數(shù)組

要獲得數(shù)組的單個(gè)標(biāo)量,使用?[]?和?$?印記。在 Perl 中所有數(shù)組都從 0 開(kāi)始。

$stooges[1] # Curly

數(shù)組也能使用負(fù)偏移從尾端訪問(wèn)。

$stooges[-1] # Iggy

讀取不存在的元素將得到?undef。

$stooges[47] # undef

數(shù)組的長(zhǎng)度是標(biāo)量值

將數(shù)組放到標(biāo)量環(huán)境能得到其長(zhǎng)度。一些人也喜歡直接使用?scalar

my $stooge_count = scalar @stooges; # 4

my $stooge_count = @stooges;        # 4

不要使用?length?來(lái)獲得數(shù)組的長(zhǎng)度。那只會(huì)得到字符串的長(zhǎng)度。

my $moe_length = length $stooges[@stooges/2];
                 length $stooges[2];
                 length 'Moe';
                 3;

數(shù)組沒(méi)有邊界

數(shù)組沒(méi)有任何有限的大小,且不必預(yù)先聲明。數(shù)組按需更改其大小。

數(shù)組也不稀疏。下列代碼創(chuàng)建 10,000 個(gè)元素的數(shù)組。

my @array     = ();
$array[10000] = 'x';

@array?現(xiàn)在具有 10,001 個(gè)元素(0-10,000)。它只填入了一個(gè),其他 10,000 個(gè)都是undef。

數(shù)組會(huì)平展,但不會(huì)嵌套

不像 PHP,當(dāng)數(shù)組合并時(shí)會(huì)平展開(kāi)為一個(gè)大列表。

my @sandwich       = ( 'PB', 'J' );
my @other_sandwich = ( 'B', 'L', 'T' );
my @ingredients    = ( @other_sandwich, @sandwich );
# ( 'B', 'L', 'T', 'PB', 'J' )

這意味著你不能將一個(gè)數(shù)組包含到另一個(gè)數(shù)組或哈希中。那樣的話,你將需要使用引用。

列表能帶擴(kuò)展的逗號(hào)(,)

Perl 最好的特性之一是在列表的尾端能帶一個(gè)擴(kuò)展的逗號(hào)。例如:

my @array = (
    'This thing',
    'That thing',
);

當(dāng)你編輯代碼時(shí),這使添加或者刪除項(xiàng)目十分容易,因?yàn)槟銦o(wú)需將最后一個(gè)項(xiàng)目作為特殊情況處理。

my @array = (
    'This thing',
    'That thing',
    'The other thing',
);

像隊(duì)列和堆棧一樣使用數(shù)組

shift?從數(shù)組開(kāi)頭移除元素。

my $next_customer = shift @customers;

unshift?將元素添加到數(shù)組的開(kāi)頭。

unshift @customers, $line_jumper;

push?將元素添加到數(shù)組的結(jié)尾。

push @customers, $dio; # The last in line

pop?從數(shù)組的結(jié)尾移除元素。

my $went_home = pop @customers;

利用數(shù)組分片提取數(shù)組的部分元素

數(shù)組分片只是使用多個(gè)索引訪問(wèn)數(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;

注意:當(dāng)訪問(wèn)數(shù)組分片時(shí),印記是?@,不是?$。因?yàn)槟惴祷氐氖菙?shù)組,而不是標(biāo)量。新手常范的錯(cuò)誤是使用?@?印記而不是?$?訪問(wèn)一個(gè)數(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];

利用數(shù)組分片來(lái)分配數(shù)組塊

你能夠?qū)?shù)組分片作為左值(lvalues),即能賦值給等號(hào)左邊的值。

# 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];

注意:分片的左邊和右邊大小必須相同。在等號(hào)右邊缺少的值將使用?undef?換掉。

利用?splice?就地修改數(shù)組

splice?讓你拼接數(shù)組為另一個(gè)數(shù)組。讓我們來(lái)看幾個(gè)常見(jiàn)的錯(cuò)誤做法,那應(yīng)該能說(shuō)明它的有用性。

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); 其次,我們定義偏移(離我們想拼接的列表開(kāi)始有多遠(yuǎn));第三,我們指定 拼接的長(zhǎng)度;最后,我們列出想要插入的項(xiàng)目。

如果遇到錯(cuò)誤,那么通過(guò)?perldoc -f splice?來(lái)了解詳情。

利用?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ù)也會(huì)被修改。這樣,上例可以修改成:

my @array = ( 'ReD', 'bLue', 'GrEEN' );
map { $_ = ucfirst lc $_ } @array;
# @array = ( 'Red', 'Blue', 'Green' )

利用?grep?從數(shù)組選擇項(xiàng)目

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 );

我們也可以傳遞正則表達(dá)式給?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;
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)