您的位置:首页 > 其它

perl对数组的操作

2013-11-14 10:43 218 查看
本文和大家重点讨论一下Perl语法中Perl数组和列表,列表是包含在括号里的一序列的值,可以为任何数值,也可为空,如:

(1,5.3,"hello",2),空列表:()。

Perl语法   Perl数组和列表简介

一、列表
列表是包含在括号里的一序列的值,可以为任何数值,也可为空,如:(1,5.3,"hello",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");
但这样很容易混淆,故不推荐。

1、Perl数组的存取

◆对Perl数组中的值通过下标存取,第一个元素下标为0。试图访问不存在的Perl数组元素,则结果为NULL,但如果给超出Perl数组大小的元素赋值,则Perl数组自动增长,原来没有的元素值为NULL。如:

@array=(1,2,3,4);

$scalar=$array[0];

$array[3]=5;#now@arrayis(1,2,3,5)

$scalar=$array[4];#now$scalar=null;

$array[6]=17;#now@arrayis(1,2,3,5,"","",17)

◆Perl数组间拷贝

@result=@original;

◆用Perl数组给列表赋值

@list1=(2,3,4);

@list2=(1,@list1,5);#@list2=(1,2,3,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,$var2=7,$var3=""(null)

◆从标准输入(STDIN)给变量赋值

$var=<STDIN>;
@array=<STDIN>;#^D为结束输入的符号

2、字符串中的方括号和变量替换

"$var[0]"为Perl数组@var的第一个元素。

"$var\[0]"将字符"["转义,等价于"$var"."[0]",$var被变量替换,[0]保持不变。

"${var}[0]"亦等价于"$var"."[0]"。
"$\{var}"则取消了大括号的变量替换功能,包含文字:${var}.

3、列表范围:

(1..10)=(1,2,3,4,5,6,7,8,9,10)

(2,5..7,11)=(2,5,6,7,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!

4、Perl数组的输出:

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

print(@array,"\n");

结果为:123

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

print("@array\n");
结果为:123

5、列表/Perl数组的长度

当Perl数组变量出现在预期简单变量出现的地方,则PERL解释器取其长度。

@array=(1,2,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,2,3,4,5);

@subarray=@array[0,1];#@subarray=(1,2)

@subarray2=@array[1..3];#@subarray2=(2,3,4)

@array[0,1]=("string",46);#@array=("string",46,3,4,5)now

@array[0..3]=(11,22,33,44);#@array=(11,22,33,44,5)now

@array[1,2,3]=@array[3,2,4];#@array=(11,44,33,5,5)now

@array[0..2]=@array[3,4];#@array=(5,5,"",5,5)now

可以用子Perl数组形式来交换元素:

@array[1,2]=@array[2,1];

7、有关Perl数组的库函数

(1)sort--按字符顺序排序

@array=("this","is","a","test");

@array2=sort(@array);#@array2=("a","is","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数组去尾

chop的意义是去掉STDIN(键盘)输入字符串时最后一个字符--换行符。而如果它作用到Perl数组上,则将Perl数组中每一个元素都做如此处理。

@list=("rabbit","12345","quartz");

chop(@list);#@list=("rabbi","1234","quart")now

(4)join/split--连接/拆分

join的第一个参数是连接所用的中间字符,其余则为待连接的字符Perl数组。

$string=join("","this","is","a","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);

关联数组的赋值与普通数组和列表相似。

为了更好的理解关联数组引入下面这一段话:

你可以把它们想象为一组卡片。每张卡片上半部分是索引而下半部分是数值。

关联数组的操作函数

1。keys(%array)操作符可生成由关联数组%array中的所有当前关键字组成的列表。即

返回奇数个元素(第1,3,5,7...个)的列表。 

2。values(%array)操作符返回由关联数组%array中所有当前值组成的列表,即返回偶

数个列表。

3。echo(%array)操作符返回由一个关键字和一个值对构成的两个元素的表。对同一数组再操作时返回下一对值直至结束。若没有更多的对时,echo()返回空表。

4。delete $ARRAY{key};delete 是 Perl 所提供的函数,作用是删除关联数组中的一个key以及这个 key 所对应的 value。使用方法是 在delete 函数之后,指定关联数组中要删除的key名称。

5。 exists (element)在Perl5中定义,判断关联数组中是否存在某元素,若存在,返回非零值(真),否则返回零值(假)。

Perl的数组操作有四大常用函数,分别是:

push:从数组的末尾加入元素。

pop :从数组的末尾取出元素

shift: 从数组的开头取出元素

unshift:从数组的开头加入元素

其应用具体如下:

1、push

#!/usr/bin/perl

use strict;

use warnings;

my @array = ();

for ( my $i = 1 ; $i <= 5 ; ++$i ) {

    push @array, $i;

    print "@array\n";

}

output:

1

1 2

1 2 3

1 2 3 4

1 2 3 4 5

2、pop

#!/usr/bin/perl

####<pop>###

use strict;

use warnings;

my @array = ( 1, 2, 3, 4, 5, 6 );

while (@array) {

    my $firstTotal = pop(@array);

    print "@array\n";

}

output:

1 2 3 4 5

1 2 3 4

1 2 3

1 2

1

3、shift

#!/usr/bin/perl

####<shift>###

use strict;

use warnings;

my @array = ( 1, 2, 3, 4, 5, 6 );

while (@array) {

    my $firstTotal = shift(@array);

    print "@array\n";

}

output:

2 3 4 5 6

3 4 5 6

4 5 6

5 6

6

4、unshift

#!/usr/bin/perl

####<unshift>###

use strict;

use warnings;

my @array = ();

for ( my $i = 1; $i <= 5; ++$i ) {

   unshift( @array, $i );         # add $i to front of @array

   print "@array\n";              # display current @array

}

output:

1

2 1

3 2 1

4 3 2 1

5 4 3 2 1

另外,perl的数组还有其它重要函数,如splice、subtr、split、join、sort等。

5、splice 操作数组中间部分的函数,该函数主要有2个作用:

5.1、向数组中间插入内容

#!/usr/bin/perl

use strict;

use warnings;

my @array = ( 0 .. 6 );

my @array1 = ( 'a' .. 'd' );

my @replaced = splice( @array, 3, 2, @array1 );

print "replaced:     @replaced\n",

      "with:         @array1\n",

      "resulting in: @array\n\n";

output:

replaced:     3 4

with:         a b c d

resulting in: 0 1 2 a b c d 5 6

5.2、删除数组元素

#!/usr/bin/perl

use strict;

use warnings;

my @array  = ( 0 .. 6 );

my @array1 = ( 'a' .. 'd' );

my @replaced = splice( @array, 3, 2 );

print "replaced:     @replaced\n",

      "resulting in: @array\n\n";

output:

replaced:     3 4

with:         a b c d

resulting in: 0 1 2 5 6

删除到末尾

#!/usr/bin/perl

use strict;

use warnings;

my @array  = ( 0 .. 6 );

my @array1 = ( 'a' .. 'd' );

my @replaced = splice( @array, 3 );

print "replaced:     @replaced\n",

      "resulting in: @array\n\n";

output:

replaced:     3 4 5 6

resulting in: 0 1 2

6、join 连接列表中的各个分离的串,生成一个新的串,返回一个标量!

#!/usr/bin/perl

use strict;

use warnings;

my @array = ( 0 .. 6 );

my $replaced = join("\n", @array);

print "$replaced\n",

output:

0

1

2

3

4

5

6

7、split

把字符串进行分割并把分割后的结果放入数组中

 perl -le '$p=q(/var/ftp/test);@a=split(/\/ftp\//,$p);print $a[1];'

test

 perl -le '$p=q(/var/ftp/test);@a=split(/\/ftp\//,$p);print $a[0];'

/var 

8、scalar

统计数组的长度,一般我们不用这个,直接将数组赋值给标量即可。

#!/usr/bin/perl

use strict;

use warnings;

my @array = ( 0 .. 6 );

my $count1 = @array;

my $count2 = scalar @array;

print "$count1\n";

print "$count2\n";

output:

7

7

9、sort

对数组元素进行排序

#!/usr/bin/perl

use strict;

use warnings;

my @array    = ( 0 .. 9 );

my @reversed = reverse @array;

print "Original:    @array\n";

print "Reversed:    @reversed\n\n";

# create an unsorted array of numbers and sort it

my @array2            = ( 100, 23, 9, 75, 5, 10, 2, 50, 7, 96, 1, 40 );

my @sortedLexically   = sort @array2;

my @sortedNumerically = sort { $a <=> $b } @array2;

print "Unsorted:    @array2\n";

print "Lexically:   @sortedLexically\n";

print "Numerically: @sortedNumerically\n";

output:

Original:    0 1 2 3 4 5 6 7 8 9

Reversed:    9 8 7 6 5 4 3 2 1 0

Unsorted:    100 23 9 75 5 10 2 50 7 96 1 40

Lexically:   1 10 100 2 23 40 5 50 7 75 9 96

Numerically: 1 2 5 7 9 10 23 40 50 75 96 100

如何判断某个数组中是否存在某个元素

如果数组是@array类型,则有两种判断方法:

1.循环判断,好处是可以获取该元素的索引。

my@array=qw(var1
var2 var3);
my %pos;
my $index= 0;
map {$pos{$_}=$index++}@array;

if(exists$pos{var1}){
warn "yes/n";
}


2.智能匹配判断,好处是代码简洁。
if($elem~~@array)
 #该方法数组中不能有null值 否则会影响判断

如果$elem是数值类型的,则使用:
if($elem+
0 ~~@array)

实例如下:
my@array=qw(1
2 3 4);
my $elem="1";
if ($elem+ 0~~@array)
{

   print
"yes/n";
}

如果数组是%hash类型的话,则更加简单,可以直接使用:

if(exists$hash{$key})


二维数组:

实例运用:  @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", "barney", "pebbles", "bambam", "dino", ],

               [ "george", "jane", "elroy", "judy", ],

               [ "homer", "bart", "marge", "maggie", ],

              ];

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", "barney", "pebbles", "bambam", "dino", ],

           [ "george", "jane", "elroy", "judy", ],

           [ "homer", "bart", "marge", "maggie", ],

          );

say $AoA[2][1];

$ref_to_AoA = [

               [ "fred", "barney", "pebbles", "bambam", "dino", ],

               [ "george", "jane", "elroy", "judy", ],

               [ "homer", "bart", "marge", "maggie", ],

              ];

print_AoA();

my @tmp = (1, 2, 3, 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], "wilma", "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 : @$aref\n";

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);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: