Perl分片技術

分片(slice)

在perl中,若是想要取得一部分變量、一部分列表內容、一部分hash內容,能夠採用分片(切片)的方式。php

注意,perl並未提供字符串的切片方式,但可使用內置函數substr()來實現同樣的功能。python

空變量賦值

例如,有些語言(如golang)支持空變量賦值(如golang),以便丟棄那些不許備使用的變量,perl也支持,只需在不想使用的位置上設置undef便可。golang

例如,下面的變量列表中,就丟棄了php和ruby對應的賦值操做。shell

@arr=qw(python perl shell php ruby);
($py,$perl,$shell,undef,undef) = @arr;

perl中有些函數(好比stat和localtime)在列表上下文會返回不少個字段值列表,這時空變量賦值的方式就排上用場了:數組

($sec,$min,$hour,$mday,$mon,$year,undef,undef,undef) = localtime();

可是這樣的賦值方式仍是麻煩,弄錯了undef的位置和數量,就會出錯,並且有些時候只是想取得值即刻使用,而不想將其賦值給變量存儲起來再經過變量來引用。因而,切片就排上用場了。ruby

數組切片

先看列表切片:函數

qw(aaa bbb ccc ddd)[1,2];

這表示將列表(aaa bbb ccc ddd)進行切片,取出其中索引位爲1和2的元素,因爲索引位從0開始計算,因此表示取出(bbb ccc)。code

  • 切片返回的是一個列表,因此能夠方便地對取出的元素賦值
  • 切片中括號中的索引值只要不越界,能夠隨意寫,且能夠重複
  • 切片的索引中須要的一個列表
  • "-1"索引位表示從後向前取的倒數第一個元素,同理"-2"表示倒數第二個
  • 中括號中的逗號不是表示範圍,而是索引位分隔符

例如,下面的例子中屢次取了索引位1和2的元素,且索引位徹底亂序的,但這些行爲都是容許的。索引

qw(aaa bbb ccc ddd perl shell python)[1,-1,3,2,0,1,2];

因爲索引位是列表,因此使用範圍序列的方式也是容許的:字符串

qw(aaa bbb ccc ddd perl shell python)[1..3]; # 等價於 [1,2,3]

再看數組切片。所謂數組切片,其實是將數組轉換爲列表(數組底層就是列表),再經過列表的有序性來切片。例如:

@arr = qw(aaa bbb ccc ddd);
($a,$b) = @arr[1,3];
print $a,$b;

多數時候,數組切片和列表切片是等價的,可是有兩點不一樣:

  1. 數組切片能夠放在雙引號中被解析,從而進行數組的切片替換,而列表切片則不能解析
  2. 能夠將一系列值賦值給數組切片(也就是切片表達式在等號左邊),從而實現修改數組元素的目的

第一點,示例以下:

@arr=qw(perl python shell php);
print "@arr[1,2,3]\n";                  # 成功切片
print  qw(aaa bbb ccc ddd)[1,2],"\n";   # 成功切片
print "qw(aaa bbb ccc ddd)[1,2]\n";     # 不會切片,而是直接當字符串輸出

第二點,示例以下:

@arr=qw(perl python shell php);
@arr[1,2]=qq(cpython csh);    # 將數組的元素python改成cpython,shell改成csh
print "new arr: @arr\n";

範圍切片時使用M..N的方式,若是想要切到倒數第2個元素呢?指定N爲-2嗎?這確定是錯的。因此若是想切到倒數第某個元素,可使用($#arr-N+1)的方式來表示倒數第N個,例如5個元素的數組,$#arr爲4,倒數第1個爲$#arr - 0,倒數第二個爲$#arr - 1。示例:

@arr=qw(perl python shell php);
print @arr[0..($#arr - 2)];

hash切片

hash切片和數組切片行爲上相似,但寫法上可能有些使人疑惑。例如:

%phone_num=(longshuai =>"18012345678",
             xiaofang =>"17012345678",
             tun_er   =>"16012345678",
             fairy    =>"15012345678");

($a,$b,$c)=@phone_num{qw(xiaofang fairy xiaofang)};
print $a,"\n",$b,"\n",$b,"\n";

幾個須要說明的地方:

  • 儘管是hash切片,切片使用的符號仍然是@,例如@hash_name
  • 切片過程使用大括號包圍想要取得的hash鍵列表
  • 切片的索引是hash鍵,而非從0開始計算的數值索引位
  • 取多個切片元素時,大括號中的hash鍵是一個由鍵組成的列表
  • 能夠將一系列值賦值給hash切片(也就是切片表達式在等號左邊),從而實現修改hash元素值的目的
  • hash是不能在雙引號中進行替換的,可是hash切片能夠在雙引號中替換

如下三種hash鍵形式都是容許的:

@phone_num{qw(xiaofang fairy xiaofang)};
@phone_num{("xiaofang","fairy","xiaofang")};
@phone_num{"xiaofang","fairy","xiaofang"};

和數組切片能夠賦值同樣,也能夠爲hash的切片元素賦值,從而實現修改對應鍵值對的值。

%phone_num=(longshuai =>"18012345678",
             xiaofang =>"17012345678",
             tun_er   =>"16012345678",
             fairy    =>"15012345678");

@number=qw(18087654321 17087654321);
@phone_num{qw/longshuai xiaofang/} = (@number);
print "@phone_num{qw/longshuai xiaofang/}","\n";
相關文章
相關標籤/搜索