【perl 文件中文化計畫】perl 二維陣列教程翻譯完成。
[code]name
perllol - 運算元組的陣列(二維陣列)
說明宣告和訪問陣列的陣列
建立乙個陣列的陣列(有時也可以叫「列表的列表」,不過不太準確)真是再簡
單也不過了。它相當容易理解,並且本文中出現的每個例子都有可能在實際應用
中出現。
陣列的陣列就是乙個普通的陣列(@aoa),不過可以接受兩個下標("$aoa[3][2])。
下面先定義乙個這樣的陣列: "
# 乙個包含有「指向陣列的引用」的陣列
@aoa = (
[ "fred", "barney" ],
[ "george", "jane", "elroy" ],
[ "homer", "marge", "bart" ],
);print $aoa[2][2];
bart
你可能已經注意到,外面的括號是圓括號,這是因為我們想要給陣列賦值,所以
需要圓括號。如果你*不*希望這裡是 @aoa,而是乙個指向它的引用,那麼就得
這樣:# 乙個指向「包含有陣列引用的陣列」的引用
$ref_to_aoa = [
[ "fred", "barney", "pebbles", "bambam", "dino", ],
[ "homer", "bart", "marge", "maggie", ],
[ "george", "jane", "elroy", "judy", ],
];print $ref_to_aoa->[2][2];
注意外面的括號現在變成了方括號,並且我們的訪問語法也有所改變。這時因為
和 c 不同,在 perl 中你不能自由地交換陣列和引用(在 c 中,陣列和指標在
很多地方可以互相代替使用)。$ref_to_aoa 是乙個陣列引用,而 @aoa 是乙個
陣列。同樣地,$aoa[2] 也不是乙個陣列,而是乙個陣列引用。所以下面這
兩行:$aoa[2][2]
$ref_to_aoa->[2][2]
也可以用這兩行來代替:
$aoa[2]->[2]
$ref_to_aoa->[2]->[2]
這是因為這裡有兩個相鄰的括號(不管是方括號還是花括號),所以你可以隨意
地省略箭頭符號。但是如果 $ref_to_aoa 後面的那個箭頭不能省略,因為省略
了就沒法知道 $ref_to_aoa 到底是引用還是陣列了 ^_^。
修改二維陣列
前面的例子裡我們建立了包含有固定資料的)二維陣列,但是如何往其中新增新元
素呢?再或者如何從零開始建立乙個二維陣列呢?
首先,讓我們試著從乙個檔案中讀取二維陣列。首先我們演示如何一次性新增一
單詞代表了二維陣列的乙個元素。下面的**可以把它們儲存到 @aoa:
while (<>)
你也可以用乙個函式來一次讀取一行:
for $i ( 1 .. 10 )
或者也可以用乙個臨時變數來中轉一下,這樣看起來更清楚些:
for $i ( 1 .. 10 )
注意方括號 "" 在這裡非常重要。方括號實際上是陣列引用的構造器。如果不
用方括號而直接寫,那就犯了很嚴重的錯誤:
$aoa[$i] = @tmp;
你看,把乙個陣列賦值給了乙個標量,那麼其結果只是計算了 @tmp 陣列的元素個
數,我想這肯定不是你希望的)。
如果你開啟了 "use strict",那麼你就得先定義一些變數然後才能避免警告:
use strict;
my(@aoa, @tmp);
while (<>)
當然,你也可以不要臨時變數:
while (<>)
如果你知道想要放在什麼地方的話,你也可以不要 push(),而是直接進行賦值:
my (@aoa, $i, $line);
for $i ( 0 .. 10 )
甚至是這樣:
my (@aoa, $i);
for $i ( 0 .. 10 )
你可能生怕 <> 在列表上下文會出差錯,所以想要明確地宣告要在標量上下文中
對 <> 求值,這樣可讀性會更好一些:(譯者注:列表上下文中,<>
返回所有的行,標量上下文中 <> 只返回一行。)
my (@aoa, $i);
for $i ( 0 .. 10 )
如果你想用 $ref_to_aoa 這樣的乙個引用來代替陣列,那你就得這麼寫:
while (<>)
現在你已經知道如何新增新行了。那麼如何新增新列呢?如果你正在做數學中的
矩陣運算,那麼要完成類似的任務:
for $x (1 .. 10) }
for $x ( 3, 7, 9 )
想要訪問的(9php.com)某個元素是不是存在是無關緊要的因為如果不存在那麼 perl 會給
你自動建立!新建立的元素的值是 "undef"。
如果你想新增到一行的末尾,你可以這麼做:
# 新增新列到已存在的行
push @, "wilma", "betty";
注意我*沒有*這麼寫:
push $aoa[0], "wilma", "betty";
# 錯誤!
事實上,上面這句根本就沒法通過編譯!為什麼?因為 push() 的第乙個引數必
須是乙個真實的陣列,不能是引用。
訪問和列印
現在是列印二維陣列的時候了。那麼怎麼列印?很簡單,如果你只想列印乙個元
素,那麼就這麼來一下:
print $aoa[0][0];
如果你想列印整個陣列,那你可不能這樣:
print @aoa;
# 錯誤!
因為你這麼做只能得到一列引用,perl 從來都不會自動地為你解引用。作為替
代,你必須得弄個迴圈或者是雙重迴圈。用 shell 風格的 for() 語句就可以
列印整個二維陣列:
for $aref ( @aoa )
如果你要用下標來遍歷的(9php.com)話,你得這麼做:
for $i ( 0 .. $#aoa ) ],\n"; }
或者這樣用雙重迴圈(注意內迴圈):
for $i ( 0 .. $#aoa ) ) }
如同你看到的一樣,它有點兒複雜。這就是為什麼有時候用臨時變數能夠看起來
更簡單一些的原因:
for $i ( 0 .. $#aoa ) ) }
哦,好像還有點複雜,那麼試試這樣:
for $i ( 0 .. $#aoa ) }
切片切片是指數組的一部分。如果你想要得到多維陣列的乙個切片,那你得進行一些
下標運算。通過箭頭可以方便地為單個元素解引用,但是訪問切片就沒有這麼好
的事了。當然,我們可以通過迴圈來取切片。
我們先演示如何用迴圈來獲取切片。我們假設 @aoa 變數的值和前面一樣。
@part = ();
$x = 4;
for ($y = 7; $y < 13; $y++)
這個迴圈其實可以用乙個切片操作來代替:
@part = @ [ 7..12 ];
不過這個看上去似乎略微有些複雜。
下面再教你如何才能得到乙個 *二維切片*, 比如 $x 從 4 到 8,$y 從 7 到
12,應該怎麼寫?
@newaoa = ();
for ($startx = $x = 4; $x <= 8; $x++) }
也可以省略掉中間的那層迴圈:
for ($x = 4; $x <= 8; $x++) [ 7..12 ] ]; }
其實用 map 函式可以更加簡練:
@newaoa = map [ 7..12 ] ] } 4 .. 8;
雖然你的經理也許會抱怨這種難以理解的**可能會帶來安全隱患,
然而這種觀點還是頗有爭議的(9php.com)(興許還可以更加安全也說不定 ^_^)。
換了是我,我會把它們放進乙個函式中實現:
@newaoa = splice_2d( \@aoa, 4 => 8, 7 => 12 );
sub splice_2d [ $y_lo .. $y_hi ] ]
} $x_lo .. $x_hi; }
參見perldata(1), perlref(1), perldsc(1)
作者tom christiansen
last update: thu jun 4 16:16:23 mdt 1998
翻譯者及翻譯宣告
本文由 flw ("[email protected]") 翻譯,翻譯成果首次出現在 *中國 perl 協會*
的協作開發平台上。
perlchina.org 本著「在國內推廣 perl」 的(目的),組織人員翻譯本文。讀者可
以在遵守原作者許可協議、尊重原作者及譯作者勞動成果的前提下,任意發布或
修改本文。
本文作者用一種輕鬆地口吻簡要介紹了一下二維陣列的用法,但是正因如此,文
中有些內容直譯過來反而很拗口、很難懂(畢竟中西方文化不同嘛),因此譯者
在翻譯時,對原文有較多的修改。喜歡閱讀英文原版勝過喜歡翻譯版的朋友們,
可以直接看原版 ^_^,同時也希望能夠理解譯者的一篇苦心,而不要在背後罵我
翻譯得不對就是了。
perl 二維陣列
perl沒有真正的二維陣列,所謂的二維陣列其實是把一維陣列以引用的方式放到另外乙個一維陣列。二維陣列定義 my array1 1,2 3,4 45,9 66,5 使用表示匿名陣列 或者 my array2 qw this is a array my array3 another array my a...
Perl 二維陣列
7 切片 此處引用相當於c中的指標。二維陣列第一列不儲存具體元素而是儲存指向該行一維陣列的引用。my aoa fred barney pebbles bambam dino george jane elroy judy homer bart marge maggie ref to aoa fred ...
perl二維陣列
出處 7 切片 此處引用相當於c中的指標。二維陣列第一列不儲存具體元素而是儲存指向該行一維陣列的引用。my aoa fred barney pebbles bambam dino george jane elroy judy homer bart marge maggie ref to aoa fr...