Like Share Discussion Bookmark Smile

J.J. Huang   2021-03-09   Perl   瀏覽次數:

Perl - 第六章 | Perl 數組

數組一個是存儲標量值的無序列表變量。

數組變量以 @ 開頭。訪問數組元素使用 $ + 變量名稱 + [索引值] 格式來讀取,這是使用數組變量的簡單範例:

1
2
3
4
5
6
7
8
9
10
11
#!/usr/bin/perl

@ages = (25, 30, 40);
@names = ("J.J.", "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 會將其理解為變量並打印其值。執行後,將產生以下結果:

1
2
3
4
5
6
$ages[0] = 25
$ages[1] = 30
$ages[2] = 40
$names[0] = J.J.
$names[1] = Lisa
$names[2] = Kumar

在 Perl 中,列表和數組術語經常被使用,就好像它們是可互換的一樣。但是列表是資料,而數組是變量。

數組建立

數組變量以@符號為前綴,並使用括號或 qw 運算符填充。例如:

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

第二行使用qw //運算符,該運算符返回字符串列表,並用空格分隔定界的字符串。在這個例子中,這導致了一個四元素數組。第一個元素是”This”,最後一個元素(第四個)是”array”。這意味著你可以使用不同的行,如下範例:

1
2
3
4
@days = qw/Monday
Tuesday
...
Sunday/;

你還可以通過分別分配每個值來填充數組,如下所示:

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

訪問數組元素

從數組訪問單個元素時,必須在變量前加一個美元符號($),然後在變量名稱後的方括號內附加元素索引。例如:

1
2
3
4
5
6
7
8
9
10
#!/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";

這將產生以下結果:

1
2
3
4
5
6
Mon
Tue
Wed
Sun
Sun
Mon

數組索引從零開始,因此要訪問第一個元素,你需要將 0 用作索引。你還可以給出一個負索引,在這種情況下,你可以從數組的結尾而不是開頭選擇元素。這意味著以下內容:

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

序號數組

Perl 提供了用於連續數字和字母的快捷方式。例如,當計數到 100 時,不必鍵入每個元素,而是可以執行以下操作:

1
2
3
4
5
6
7
8
9
#!/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
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

數組大小

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

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

返回的值將始終是數組的物理大小,而不是有效元素的數量。你可以證明這一點,並且使用此片段,標量@array和$#array之間的區別如下:

1
2
3
4
5
6
7
8
9
10
#!/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";

這將產生以下結果:

1
2
Size: 51
Max Index: 50

數組中只有四個元素包含訊息,但是數組的長度為51個元素,最高索引為50。

在數組中添加和刪除元素

Perl提供了許多有用的功能來添加和刪除數組中的元素。你可能有一個問題是什麼功能?到目前為止,你已經使用打印功能來打印各種值。同樣,還有其他各種功能或有時稱為子例程的子例程,可用於各種其他功能。

序號 類型與說明
1 push @ARRAY, LIST 將列表的值放到數組的末尾
2 pop @ARRAY 彈出數組最後一個值,並返回它
3 shift @ARRAY 彈出數組第一個值,並返回它。數組的索引值也依次減一。
4 unshift @ARRAY, LIST 將列表放在數組前面,並返回新數組的元素個數。

範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/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
2
3
4
5
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

切片數組元素

你還可以從數組中提取”切片”-也就是說,你可以從數組中選擇多個項目以生成另一個數組。

1
2
3
4
5
6
7
#!/usr/bin/perl

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

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

print "@weekdays\n";

這將產生以下結果:

1
Thu Fri Sat

切片的規範必須具有有效索引列表,這些索引可以是正數或負數,每個索引之間都用逗號分隔。為了提高速度,你還可以使用.. range運算符:

1
2
3
4
5
6
7
#!/usr/bin/perl

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

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

print "@weekdays\n";

這將產生以下結果:

1
Thu Fri Sat

更換數組元素

現在,我們將引入另一個名為splice()的函數,該函數具有以下語法:

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

參數說明:

  • @ARRAY:要替換的數組。
  • OFFSET:起始位置。
  • LENGTH:替換的元素個數。
  • LIST:替換元素列表。

此函數將刪除由OFFSET和LENGTH指定的@ARRAY元素,並使用LIST(如果指定)替換它們。最後,它返回從數組中刪除的元素。以下是範例:

1
2
3
4
5
6
7
#!/usr/bin/perl

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

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

這將產生以下結果:

1
2
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將5個元素從6替換為10。

將字符串轉換為數組

Perl 中將字符串轉換為數組使用split() 函數,語法格式如下:

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

參數說明:

  • PATTERN:分隔符,預設為空格。
  • EXPR:指定字符串數。
  • LIMIT:如果指定該參數,則返回該數組的元素個數。

此函數將字符串拆分為字符串數組,然後將其返回。如果指定了LIMIT,則最多分割為該數量的字段。如果省略PATTERN,則在空白處分割。以下是範例:

1
2
3
4
5
6
7
8
9
10
11
12
#!/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

這將產生以下結果:

1
2
Roses
Michael

將數組轉換為字符串

Perl 中將數組轉換為字符串使用join() 函數,語法格式如下:

1
join EXPR, LIST

參數說明:

  • EXPR:連接符。
  • LIST:列表或數組。

此函數將LIST的單獨字符串連接到單個字符串中,這些字段的字段由EXPR的值分隔,然後返回該字符串。以下是範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/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";

這將產生以下結果:

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

排序數組

Perl 中數組排序使用sort() 函數,語法格式如下:

1
sort [ SUBROUTINE ] LIST

參數說明:

  • SUBROUTINE:指定規則。
  • LIMIT:列表或數組。

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

1
2
3
4
5
6
7
8
9
#!/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";

這將產生以下結果:

1
2
Before: pizza steak chicken burgers
After: burgers chicken pizza steak

請注意,排序是根據單詞的 ASCII 數字值進行的。因此,最好的選擇是首先將數組的每個元素轉換為小寫字母,然後執行排序功能。

$ [特殊變量

特殊變量$[表示數組的第一索引值,一般都為0 ,如果我們將$[設置為1,則數組的第一個索引值即為1,第二個為2,以此類推。範例如下:

1
2
3
4
5
6
7
8
9
10
11
#!/usr/bin/perl

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

# Let's reset first index of all the arrays.
$[ = 1;

print "Food at \@foods[1]: $foods[1]\n";
print "Food at \@foods[2]: $foods[2]\n";

這將產生以下結果:

1
2
3
Foods: pizza steak chicken burgers
Food at @foods[1]: pizza
Food at @foods[2]: steak

合併陣列

由於數組只是逗號分隔的值序列,因此可以將它們組合在一起,如下範例:

1
2
3
4
5
#!/usr/bin/perl

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

print "numbers = @numbers\n";

這將產生以下結果:

1
numbers = 1 3 4 5 6

嵌入式陣列只是成為主陣列的一部分,如下範例:

1
2
3
4
5
6
7
8
#!/usr/bin/perl

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

@numbers = (@odd, @even);

print "numbers = @numbers\n";

這將產生以下結果:

1
numbers = 1 3 5 2 4 6

從列表中選擇元素

列表符號與數組的符號相同。你可以通過在列表中添加方括號並給出一個或多個索引來從數組中提取元素:

1
2
3
4
5
#!/usr/bin/perl

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

print "value of var = $var\n"

這將產生以下結果:

1
value of var = 1

同樣,我們可以提取切片,儘管不需要前導@字符-

1
2
3
4
5
#!/usr/bin/perl

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

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

這將產生以下結果:

1
Value of list = 4 3 2

註:以上參考了
Tutorialspoint, Perl - Arrays