perl对数组的操作
本文和大家重点讨论一下Perl语法中Perl数组和列表,列表是包含在括号里的一序列的值,可以为任何数值,也可为空,如: (1,5.3,"hello",2),空列表:()。Perl语法 ? Perl数组和列表简介 一、列表 列表是包含在括号里的一序列的值,可以为任何数值,也可为空,如:(1,2),空列表:()。 注:只含有一个数值的列表(如:(43.2))与该数值本身(即:43.2)是不同的,但它们可以互相转化或赋值。 列表例: ? ( ? 17,$var,"astring") (17,26<<2) (17,$var1+$var2) ($value,"Theansweris$value") 二、Perl数组--列表的存贮列表存贮于Perl数组变量中,与简单变量不同,Perl数组变量以字符"@"打头,如: @array=(1,2,3); 注: (1)Perl数组变量创建时初始值为空列表:()。 (2)因为PERL用@和$来区分Perl数组变量和简单变量,所以同一个名字可以同时用于Perl数组变量和简单变量,如: $var=1; @var=(11,27.1,"astring"); 但这样很容易混淆,故不推荐。 ◆对Perl数组中的值通过下标存取,第一个元素下标为0。试图访问不存在的Perl数组元素,则结果为NULL,但如果给超出Perl数组大小的元素赋值,则Perl数组自动增长,原来没有的元素值为NULL。如: @array=(1,3,4); $scalar=$array[0]; $array[3]=5;#now@arrayis(1,5) $scalar=$array[4];#now$scalar=null; $array[6]=17;#now@arrayis(1,5,"",17) ◆Perl数组间拷贝 @result=@original; ◆用Perl数组给列表赋值 @list1=(2,4); @list2=(1,@list1,5);#@list2=(1,4,5) ◆Perl数组对简单变量的赋值 (1)@array=(5,7,11); ($var1,$var2)=@array;#$var1=5,$var2=7,11被忽略 (2)@array=(5,7); ($var1,$var2,$var3)=@array;#$var1=5,$var3=""(null) ◆从标准输入(STDIN)给变量赋值 $var=<STDIN>; @array=<STDIN>;#^D为结束输入的符号 "$var[0]"为Perl数组@var的第一个元素。 "$var[0]"将字符"["转义,等价于"$var"."[0]",$var被变量替换,[0]保持不变。 "${var}[0]"亦等价于"$var"."[0]"。 "${var}"则取消了大括号的变量替换功能,包含文字:${var}. (1..10)=(1,6,8,9,10) (2,5..7,11)=(2,11) (3..3)=(3) ◆用于实数 (2.1..5.3)=(2.1,3.1,4.1,5.1) (4.5..1.6)=() ◆用于字符串 ("aaa".."aad")=("aaa","aab","aac","aad") @day_of_month=("01".."31") ◆可包含变量或表达式 ($var1..$var2+5) ◆小技巧: $fred="Fred"; print(("Hello,".$fred."!n")x2); 其结果为: Hello,Fred! Hello,Fred! (1)@array=(1,3); print(@array,"n"); 结果为:123 (2)@array=(1,3); print("@arrayn"); 结果为:123 当Perl数组变量出现在预期简单变量出现的地方,则PERL解释器取其长度。 @array=(1,3); $scalar=@array;#$scalar=3,即@array的长度 ($scalar)=@array;#$scalar=1,即@array第一个元素的值 注:以Perl数组的长度为循环次数可如下编程: ? $count=1; while($count<=@array){ print("element$count:$array[$count-1]n"); $count++; } 6、子Perl数组 @array=(1,5); @subarray=@array[0,1];#@subarray=(1,2) @subarray2=@array[1..3];#@subarray2=(2,4) @array[0,1]=("string",46);#@array=("string",46,5)now @array[0..3]=(11,22,33,44);#@array=(11,44,5)now @array[1,3]=@array[3,4];#@array=(11,5)now @array[0..2]=@array[3,4];#@array=(5,5)now 可以用子Perl数组形式来交换元素: @array[1,2]=@array[2,1]; 7、有关Perl数组的库函数 (1)sort--按字符顺序排序 @array=("this","is","a","test"); @array2=sort(@array);#@array2=("a","test","this") @array=(70,100,8); @array=sort(@array);#@array=(100,70,8)now (2)reverse--反转Perl数组 @array2=reverse(@array); @array2=reversesort(@array); (3)chop--Perl数组去尾 @list=("rabbit","12345","quartz"); chop(@list);#@list=("rabbi","1234","quart")now (4)join/split--连接/拆分 join的第一个参数是连接所用的中间字符,其余则为待连接的字符Perl数组。 $string=join("","this","string");#结果为"thisisastring" @list=("words","and"); $string=join("::",@list,"colons");#结果为"words::and::colons" @array=split(/::/,$string);#@array=("words","and","colons")now 关联数组(类似hash表或者json) 为了解决普通数组的局限性----当数组很大的时候遍历起来就会很困难。perl 提供了一种新的数组关联数组。他的定义区别于普通数组以%打头,区别于普通数组的是 他的下标可以是任何值这样以来他的下标就可以没有任何顺序。 例如 %array1=(key1,value1,key2,value2,key3,value3);? 其结果是 $array1{key1}=value1,其中key1可以为任何值数字,字串变量等。可以看出关联数组的个数为偶数。 perl为了能更好把下标和值区分开来采用=〉方式,array1就可以改变成如下形式 %array1=(key1=>value1,key2=>value2,key3=>value3); 关联数组的赋值与普通数组和列表相似。 为了更好的理解关联数组引入下面这一段话: Perl的数组操作有四大常用函数,分别是: use warnings; }
4、unshift #!/usr/bin/perl use strict; use warnings; my @array = ( 0 .. 6 ); my $replaced = join("n",@array); output: 0 1 7、split test ?perl -le '$p=q(/var/ftp/test);@a=split(//ftp//,$p);print $a[0];'
如何判断某个数组中是否存在某个元素如果数组是@array类型,则有两种判断方法:1.循环判断,好处是可以获取该元素的索引。
2.智能匹配判断,好处是代码简洁。
二维数组: 实例运用: ?@select_col为二维数组 my @select_col; my $select_data; #while($select_data=$sth_select->fetchrow_arrayref()) #{ # if($data_str ne "") # { # $data_str="$data_str,"; # } # $data_str=$data_str."[$gid,'+',['".join("','",@{$select_data})."']]"; # } my $nn=0; while($select_data=$sth_select->fetchrow_arrayref()) { $select_col[$nn]=[@$select_data]; $nn++; } printf("读出时间%.1f seconds.n",time-$startTime); my $startTime=time; my @col_data; foreach my $aref (@select_col) { @col_data=@{$aref}; #print @col_data; if($data_str ne "") { $data_str="$data_str,"; } $data_str=$data_str.'['.$gid.",['"; for(my $nnn=0;$nnn<=@col_data;$nnn++) { if($nnn==@col_data) { $data_str=$data_str.@col_data[$nnn]."']]"; } else { $data_str=$data_str.@col_data[$nnn]."','" } } } 二维数组的基本知识: ?1 数组与引用? ?2 声明的区别? ?3 访问的区别? ?4 添加行元素? ?5 添加列元素? ?6 访问与打印? ?6.1 运算符优先级? ?6.2 访问一个? ?6.3 遍历? ?7 切片? 1 数组与引用 此处引用相当于C中的指针。 二维数组第一列不存储具体元素而是存储指向该行一维数组的引用。 2 声明的区别 ?数组用如下形式声明: 数组名前加@,之后用()。 ? my @AoA = ( ? ? ? ? ? ?[ "fred","barney","pebbles","bambam","dino",],? ? ? ? ? ?[ "george","jane","elroy","judy",? ? ? ? ? ?[ "homer","bart","marge","maggie",? ? ? ? ? ); ?引用如下形式声明: 引用名前用$,之后用[]。 ? $ref_to_AoA = [ ? ? ? ? ? ? ? ?[ "fred",? ? ? ? ? ? ? ?[ "george",? ? ? ? ? ? ? ?[ "homer",? ? ? ? ? ? ? ]; 3 访问的区别 ?数组访问 ? $AoA[$i][$j] 因为第一列数组里面存放的是引用,所以还可以这样访问: ? $AoA[$i]->[$j] ?引用访问 ? $ref_AoA->[$i][$j] 同理引用还可以这样访问: ? $ref_AoA->[$i]->[$j] 4 添加行元素 ? my (@AoA,$ref_to_AoA); sub print_AoA{ ? ? for (@AoA) { ? ? ? ? print "@{$_}n"; ? ? } ? ? print "n"; } # assign to our array,an array of array references @AoA = ( ? ? ? ? ? ?[ "fred",? ? ? ? ? ); say $AoA[2][1]; $ref_to_AoA = [ ? ? ? ? ? ? ? ?[ "fred",? ? ? ? ? ? ? ]; print_AoA(); my @tmp = (1,4); push @AoA,[@tmp]; ? ? ? ? ? ? ?# 因为数组AoA第一列需要的是引用,而@tmp是数组,直接赋值会出错。[]表示返回@tmp的引用,即把@tmp的引用push到@AoA最后一行,二维数组行数加1. print_AoA(); push @AoA,@tmp; print_AoA(); 覆盖行 ? #$AoA[0] = @tmp; ? #$AoA[0]是scalar型,而@tmp是list型,所以用默认把tmp的个数赋给$AoA[0],即$AoA[0]=4; $AoA[0] = [@tmp]; ?#overwirte print_AoA(); 5 添加列元素 ? push @{$AoA[0]},"wilma","betty"; 省略@{} ? use v5.14; ? # needed for implicit deref of array refs by array ops push $AoA[0],"betty"; ? ? ? ? ?# 在5.14版本之前不能通过,因为以前规定push的第一参数必须为数组。在新版本中当$AoA[0]中存在引用时可以通过,但无引用时不正确。 print_AoA(); my $aref = undef; #push $aref,qw/some value/; ? ? # 出错:Not an ARRAY reference my $aref = [@tmp]; push $aref,qw/some value/; ? ? # 正确,因为aref此时不是个空引用 print "$aref : @$arefn"; 6 访问与打印 ? 6.1 运算符优先级 ? $@*%& 6.2 访问一个 ? print $AoA[$i][$j]; print ref_$AoA->[$i]->[$j]; 6.3 遍历 ?最简单的一种 ? for $aref ( @AoA ) ? ? ? ? ? ? ? ?# ?$aref只是第一列里面的引用,要想访问整行必须加@,又$访问级别比@高,所以()可以省略。 { ? ? say "t [ @$aref ],"; } ?使用$# ? for my $i (0 .. $#AoA){ ? ? say "elt $i is @{$AoA[$i]}"; } ?内嵌循环 ? for my $i (0 .. $#AoA){ ? ? for my $j (0 .. $#{$AoA[$i]}){ ? ? ? ? say "elt $i,$j is $AoA[$i][$j]n"; ? ? } } 7 切片 要访问几行几列元素。和Matlab中访问矩阵的方法差不多。 ?切单行多列 ? my @part = (); my $x = 4; for (my $y = 1; $y<4; $y++){ ? ? push @part,$AoA[$x][$y]; } # 简单写法 @part = @{$AoA[4]}[1..4]; ?切多行多列 ? my @newAoA = (); for (my $startx= my $i = 1; $i<=5; $i++){ ? ? for(my $starty = my $j = 2; $j<=4; $j++){ ? ? ? ? $newAoA[$i - $startx][$j - $starty] = $AoA[$i][$j]; ? ? } } #一个循环简单写法 for (my $x = 1; $x<=5; $x++){ ? ? push @newAoA,[@{$AoA[i]}[2 .. 4]]; } ?编写函数 ? sub splice_2D{ ? ? my $lrr = shift; ? ? my($x_l,$x_h,? ? ? ?$y_l,$y_h) = @_; ? ? return map( ? ? ? ? ? ? ? ?[ @{$lrr -> [$_]} {$y_l .. $y_h}] ? ? ? ? ? ? ? )$x_l .. $x_h; } @newAoA = splice_2D(@AoA,1=>5,2=>4); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |