Perl学习笔记 数组/散列(哈希)

2017-11-29 15:50:58来源:http://www.bioinfo-scrounger.com/archives/351作者:生信笔记人点击

分享
第七城市th7cn
数组

数组中的每个元素都是单独的标量变量,并且是有序的,我们可以通过数组索引对其赋值



@array = ()
定义空数组,$#array
表示数组最后一次元素的索引值,$array[0]
表示数组第一个元素以及$array[-1]
表示数组最后一个元素等


怎么理解数组是有序这个意思呢,比如我想将有三个元素的数组赋值于一个只有两个元素的数组,那么后面的数组的第三个元素将自动被忽略,如下:


($one, $two) = ("aaa", "bbb", "ccc");

或者这么理解:


@array[2,3] = ("a", "bb");

对数组操作的话,有几个操作符:


push/pop操作符


push是将元素(或者数组)加到一个数组的尾端


push @array, 1;
push @array, @tmp;

pop则相反,是取出数组中最后一个元素


pop @array;
$a = pop @array;

shift/unshift操作符


这两个跟上面两个操作符相反,是处理数组开头的,比如shift是将数组的前一个元素取出


shift @array;

常与@ARGV搭配可一个个取出perl程序的输入参数


@file = shift @ARGV;

unshift则是跟shift相反操作,可将元素(或者数组)加到一个数组的开头


unshift @array, @tmp;

其实我觉得最好用的还是splice这个操作符,理论上行splice可以代替上面所有的操作符的功能,但是有些出于习惯和方便的原因,可能不会选择用splice代替


splice操作符可以接收4个参数,前两个是必须参数,后两个是可选参数。第一个参数当然是需要处理的数组@array,第二个参数为要操作的起始位置,第三个参数是操作的元素长度,第四个参数是要替换的列表(数组)。我们可以灵活使用这4个参数来对数组进行各种操作


splice ARRAY, OFFSET, LENGTH, LIST

对于splice的理解可以分为两部分,首先看是否赋值于新数组,比如下面两个代表着两个不同的意思


splice(@array, 2);
@result = splice(@array, 2);

前者表示删除@array数组的第3个元素到最后一个元素,后者表示将@array的第3个元素到最后一个元素赋值于@result数组(当然,@array数组其实也发生了删除元素的步骤,切记!!)


接着可以按照splice操作符使用了几个参数来分不同的作用,比如删除第3个到第5个元素或删除第3个元素


splice(@array, 2, 3);
splice(@array, 2, 1);

在数组第3个位置增加一个元素or数组


splice(@array, 3, 0, "add");
splice(@array, 3, 0, @add);

如果是替换元素呢,其实跟上述增加元素的用法是差不多的,比如用@repeat数组替换@array数组的第3到5个元素


splice(@array,2,3,@repeat);

还有以下几点需要注意的,下面这个表示返回最后一个移出的值,也就是返回@array数组的第5个元素


$result = splice(@array, 2, 3);

如果第三个参数为负数,那么第三个参数不再代表长度了,而是表示位置,如下表示移出第3个元素到最后一个元素


splice(@array, 2, -1);

如果第二个参数为负数,那么起始的位置不再是数组从头到尾了,而是从尾端的某个元素开始,如下表示移除数组@array最后2个元素


splice(@array, -2);
散列(哈希)


在Learning Perl
这本书中称其为哈希,在Intermediate Perl
这本书中则叫其为数列,当然其实我觉得还是数列更加贴切点,跟数组相对应嘛。数列是一种数据结构,能储存任意多的键以及其所对应的值,跟数组的的区别在于索引方式,数列是以”名字”来当做索引的,也称为键,键对应的储存数据则称为值。当然由于数列的键是字符串,所以在数列里面储存的数据是没有顺序的。不夸张的说,有数列的perl和没有数列的perl完全不是同一层次的语言。。。。个人觉得,因为其实在太好用了。。。。


数列中的键是必须唯一的,这跟数组的索引一样,%hash可以被这样赋值:


%hash = (key, value, key, value, key, value);


可以通过reverse
将%hash的键和值互换


%reverse_hash = reserve %hash;

其实一般是以胖箭头


%hash = (
a => "aaa",
b => "bbb",
);

可看到键没有给予引号,这是因为perl默认许可键如果是单纯的字符串是不同给引号的,比如


%hash{a} = 1;

但是不是单纯的字符串,而是表达式或者其他连接形式的话,则最好加引号,反正我徒省事,不然咋样都加引号,比如下面2个就是不同的键,前者键为aabb,后者键为aa.bb


%hash{aa.bb} = 1;
%hash{"aa.bb"} = 1;

如果想提取%hash的键和值,可以用keys函数和values函数,如果想对键排序则可再加上sort函数


@array = sort keys %hash;
@array = values %hash;

当然如果想对每一对键-值进行处理,则可以使用each函数遍历数列,而且其会记得每个上一次返回的是哪个键-值,所以其能迭代整个数列。但是如果数列重置(读取了所有元素,或者使用了keys %hash or values %hash)后,那么顺序会再次改变了


while(my ($k, $v) = each(%hash)){
print "$k=>$v/n";
}

其实我也很少用each函数,因为如果是遍历整个数列,我会使用foreach搭配key函数,因人而异了


foreach (keys %hash){
print "$_=>$hash{$_}/n";
}

判断数列的键是否存在用exists函数,但我一般用if语句根据$hash{$key}对应的值是否为空来判断键$key是否存在,如下两个写法大部分时候是等价的


if (exists $hash{$key}){
print "xxx";
}
if ($hash{$keys}){
print "xxx";
}

但是delete函数还是蛮有用的,可以删除特定的键,当然也顺便也删除了该键对应的值


delete $hash{$key};
切片

除了上述对数组和数列的操作外,还有一个比较重要的是切片,我喜欢用分割来理解,即将一个标量分割为一个数组,如下:


@array = split //;

上述默认的写法即是将$_变量按照每个字符进行分割,其实split在文件处理中,处理tab分割的每行数据更加好用


@array = split //t/, $line;

其实perl对切片的定义是比较广的,下述这种也叫做切片


$array[0,1] = ($one, $two);

所以我们经常会看到这样的用法


($one, $two) = (split //t/, $line)[0,1]

除了对数组进行切片,当然还有数列(哈希)的切片,我觉得这个非常强大!可惜总是忘记使用。。。


@array = $hash{@info}

那么要表达的就是提取出@info数组中的所有元素在%hash中作为键对应的值,并赋予数组@array;上述的复杂的写法则如下,两者的水平已经不是同一层次了。。。


foreach my $k (keys %hash) {
if (grep{$k eq $_}@info) {
push @array, $hash{$k};
}
}


本文出自于http://www.bioinfo-scrounger.com
转载请注明出处


第七城市th7cn

最新文章

123

最新摄影

闪念基因

微信扫一扫

第七城市微信公众平台