Perl - 陣列



陣列是一個變數,它儲存一個有序的標量值列表。陣列變數以“at”(@)符號開頭。要引用陣列的單個元素,您將使用美元符號($)加上變數名,後跟方括號中的元素索引。

以下是用陣列變數的一個簡單示例:

#!/usr/bin/perl

@ages = (25, 30, 40);             
@names = ("John Paul", "Lisa", "Kumar");

print "\$ages[0] = $ages[0]\n";
print "\$ages[1] = $ages[1]\n";
print "\$ages[2] = $ages[2]\n";
print "\$names[0] = $names[0]\n";
print "\$names[1] = $names[1]\n";
print "\$names[2] = $names[2]\n";

這裡我們在 $ 符號前使用了轉義符(\),只是為了列印它。否則,Perl 會將其理解為變數並列印其值。執行後,將產生以下結果:

$ages[0] = 25
$ages[1] = 30
$ages[2] = 40
$names[0] = John Paul
$names[1] = Lisa
$names[2] = Kumar

在 Perl 中,列表和陣列術語通常被交替使用。但列表是資料,陣列是變數。

陣列建立

陣列變數以 @ 符號開頭,並使用括號或 qw 運算子填充。例如:

@array = (1, 2, 'Hello');
@array = qw/This is an array/;

第二行使用 qw// 運算子,它返回一個字串列表,以空格分隔分隔的字串。在此示例中,這導致一個四元素陣列;第一個元素是 'this',最後一個(第四個)是 'array'。這意味著您可以使用不同的行,如下所示:

@days = qw/Monday
Tuesday
...
Sunday/;

您還可以透過分別分配每個值來填充陣列,如下所示:

$array[0] = 'Monday';
...
$array[6] = 'Sunday';

訪問陣列元素

訪問陣列中的單個元素時,必須在變數前加一個美元符號($) ,然後在變數名後加上方括號中的元素索引。例如:

#!/usr/bin/perl

@days = qw/Mon Tue Wed Thu Fri Sat Sun/;

print "$days[0]\n";
print "$days[1]\n";
print "$days[2]\n";
print "$days[6]\n";
print "$days[-1]\n";
print "$days[-7]\n";

這將產生以下結果:

Mon
Tue
Wed
Sun
Sun
Mon

陣列索引從零開始,因此要訪問第一個元素,您需要將 0 作為索引。您還可以提供負索引,在這種情況下,您將從陣列的末尾而不是開頭選擇元素。這意味著以下內容:

print $days[-1]; # outputs Sun
print $days[-7]; # outputs Mon

順序編號陣列

Perl 為順序數字和字母提供了一種快捷方式。例如,不必在從 1 數到 100 時鍵入每個元素,我們可以執行以下操作:

#!/usr/bin/perl

@var_10 = (1..10);
@var_20 = (10..20);
@var_abc = (a..z);

print "@var_10\n";   # Prints number from 1 to 10
print "@var_20\n";   # Prints number from 10 to 20
print "@var_abc\n";  # Prints number from a to z

這裡雙點 (..) 被稱為 **範圍運算子**。這將產生以下結果:

1 2 3 4 5 6 7 8 9 10
10 11 12 13 14 15 16 17 18 19 20
a b c d e f g h i j k l m n o p q r s t u v w x y z

陣列大小

可以使用陣列上的標量上下文確定陣列的大小 - 返回的值將是陣列中元素的數量:

@array = (1,2,3);
print "Size: ",scalar @array,"\n";

返回的值始終是陣列的物理大小,而不是有效元素的數量。您可以使用此片段演示這一點,以及標量 @array 和 $#array 之間的區別,如下所示:

#!/usr/bin/perl

@array = (1,2,3);
$array[50] = 4;

$size = @array;
$max_index = $#array;

print "Size:  $size\n";
print "Max Index: $max_index\n";

這將產生以下結果:

Size: 51
Max Index: 50

陣列中只有四個包含資訊的元素,但陣列長 51 個元素,最高索引為 50。

在陣列中新增和刪除元素

Perl 提供了許多有用的函式來在陣列中新增和刪除元素。您可能想知道什麼是函式?到目前為止,您已使用 **print** 函式列印各種值。類似地,還有各種其他函式,有時稱為子例程,可用於各種其他功能。

序號 型別和描述
1

push @ARRAY, LIST

將列表的值推送到陣列的末尾。

2

pop @ARRAY

彈出並返回陣列的最後一個值。

3

shift @ARRAY

將陣列的第一個值移出並返回它,將陣列縮短 1 並將所有內容向下移動。

4

unshift @ARRAY, LIST

將列表新增到陣列的前面,並返回新陣列中的元素數量。

#!/usr/bin/perl

# create a simple array
@coins = ("Quarter","Dime","Nickel");
print "1. \@coins  = @coins\n";

# add one element at the end of the array
push(@coins, "Penny");
print "2. \@coins  = @coins\n";

# add one element at the beginning of the array
unshift(@coins, "Dollar");
print "3. \@coins  = @coins\n";

# remove one element from the last of the array.
pop(@coins);
print "4. \@coins  = @coins\n";

# remove one element from the beginning of the array.
shift(@coins);
print "5. \@coins  = @coins\n";

這將產生以下結果:

1. @coins = Quarter Dime Nickel
2. @coins = Quarter Dime Nickel Penny
3. @coins = Dollar Quarter Dime Nickel Penny
4. @coins = Dollar Quarter Dime Nickel
5. @coins = Quarter Dime Nickel

切片陣列元素

您還可以從陣列中提取“切片” - 也就是說,您可以按順序從陣列中選擇多個專案以生成另一個數組。

#!/usr/bin/perl

@days = qw/Mon Tue Wed Thu Fri Sat Sun/;

@weekdays = @days[3,4,5];

print "@weekdays\n";

這將產生以下結果:

Thu Fri Sat

切片的規範必須包含一個有效索引列表,可以是正數或負數,每個索引之間用逗號分隔。為了提高速度,您還可以使用 **..** 範圍運算子:

#!/usr/bin/perl

@days = qw/Mon Tue Wed Thu Fri Sat Sun/;

@weekdays = @days[3..5];

print "@weekdays\n";

這將產生以下結果:

Thu Fri Sat

替換陣列元素

現在我們將介紹另一個名為 **splice()** 的函式,其語法如下:

splice @ARRAY, OFFSET [ , LENGTH [ , LIST ] ]

此函式將刪除 @ARRAY 中由 OFFSET 和 LENGTH 指定的元素,如果指定,則用 LIST 替換它們。最後,它返回從陣列中刪除的元素。以下是示例:

#!/usr/bin/perl

@nums = (1..20);
print "Before - @nums\n";

splice(@nums, 5, 5, 21..25); 
print "After - @nums\n";

這將產生以下結果:

Before - 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
After - 1 2 3 4 5 21 22 23 24 25 11 12 13 14 15 16 17 18 19 20

在這裡,實際替換從第 6 個數字開始,然後用數字 21、22、23、24 和 25 替換從 6 到 10 的五個元素。

將字串轉換為陣列

讓我們瞭解另一個名為 **split()** 的函式,其語法如下:

split [ PATTERN [ , EXPR [ , LIMIT ] ] ]

此函式將字串拆分為一個字串陣列,並返回它。如果指定了 LIMIT,則最多拆分為該數量的欄位。如果省略 PATTERN,則在空格處拆分。以下是示例:

#!/usr/bin/perl

# define Strings
$var_string = "Rain-Drops-On-Roses-And-Whiskers-On-Kittens";
$var_names = "Larry,David,Roger,Ken,Michael,Tom";

# transform above strings into arrays.
@string = split('-', $var_string);
@names  = split(',', $var_names);

print "$string[3]\n";  # This will print Roses
print "$names[4]\n";   # This will print Michael

這將產生以下結果:

Roses
Michael

將陣列轉換為字串

我們可以使用 **join()** 函式重新連線陣列元素並形成一個長標量字串。此函式具有以下語法:

join EXPR, LIST

此函式將 LIST 的各個字串連線成一個字串,欄位之間用 EXPR 的值分隔,並返回該字串。以下是示例:

#!/usr/bin/perl

# define Strings
$var_string = "Rain-Drops-On-Roses-And-Whiskers-On-Kittens";
$var_names = "Larry,David,Roger,Ken,Michael,Tom";

# transform above strings into arrays.
@string = split('-', $var_string);
@names  = split(',', $var_names);

$string1 = join( '-', @string );
$string2 = join( ',', @names );

print "$string1\n";
print "$string2\n";

這將產生以下結果:

Rain-Drops-On-Roses-And-Whiskers-On-Kittens
Larry,David,Roger,Ken,Michael,Tom

排序陣列

**sort()** 函式根據 ASCII 數字標準對陣列的每個元素進行排序。此函式具有以下語法:

sort [ SUBROUTINE ] LIST

此函式對 LIST 進行排序並返回排序後的陣列值。如果指定了 SUBROUTINE,則在排序元素時將應用 SUBTROUTINE 內部的指定邏輯。

#!/usr/bin/perl

# define an array
@foods = qw(pizza steak chicken burgers);
print "Before: @foods\n";

# sort this array
@foods = sort(@foods);
print "After: @foods\n";

這將產生以下結果:

Before: pizza steak chicken burgers
After: burgers chicken pizza steak

請注意,排序是根據單詞的 ASCII 數字值執行的。因此,最佳選擇是首先將陣列的每個元素轉換為小寫字母,然後執行排序函式。

合併陣列

因為陣列只是一個用逗號分隔的值序列,所以您可以將它們組合在一起,如下所示:

#!/usr/bin/perl

@numbers = (1,3,(4,5,6));

print "numbers = @numbers\n";

這將產生以下結果:

numbers = 1 3 4 5 6

嵌入式陣列僅成為主陣列的一部分,如下所示:

#!/usr/bin/perl

@odd = (1,3,5);
@even = (2, 4, 6);

@numbers = (@odd, @even);

print "numbers = @numbers\n";

這將產生以下結果:

numbers = 1 3 5 2 4 6

從列表中選擇元素

列表表示法與陣列的表示法相同。您可以透過將方括號附加到列表並提供一個或多個索引來從陣列中提取元素:

#!/usr/bin/perl

$var = (5,4,3,2,1)[4];

print "value of var = $var\n"

這將產生以下結果:

value of var = 1

類似地,我們可以提取切片,儘管不需要前導 @ 字元:

#!/usr/bin/perl

@list = (5,4,3,2,1)[1..3];

print "Value of list = @list\n";

這將產生以下結果:

Value of list = 4 3 2
廣告