perl map.doc_第1页
perl map.doc_第2页
perl map.doc_第3页
perl map.doc_第4页
perl map.doc_第5页
已阅读5页,还剩2页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

仙子注:以下文档主要译自网络,加上仙子自己的解释整理而成。简简单单讲map(一)map函数map BLOCK LISTmap EXPR, LISTmap函数对LIST里的每个元素按BLOCK或EXPR进行计算,遍历LIST时,临时将LIST里的每个元素赋值给$_变量。map对每次的计算返回一个结果列表,它在列表上下文里计算BLOCK或EXPR。每个LIST元素可能在输出列表里产生0个,1个,或多个元素。(仙子注:上文是说遍历每个LIST元素时产生一个结果列表,而不是说总的map结果是个列表,不要搞混了哦。)在标量上下文里,map返回结果列表的元素数量。在HASH上下文里,输出列表(a,b,c,d.)会变成这样的形式: ( a =; b, c =; d, . )。假如输出列表的元素数量非对称,那么最后的hash元素的值就是undef了。避免在BLOCK或EXPR里修改$_,因为这会修改LIST里的元素。另外,避免使用map返回的的列表作为左值,因为这也会修改LIST里的元素。(所谓左值,就是在某个表达式左边的变量。)(二)Map vs. grep vs. foreachmap跟grep一样,从数组里选择元素。下列2句是一样的:selected = grep EXPR, input;selected = map if (EXPR) $_ input;另外,map也是foreach陈述的特殊形式。假如transformed数组当前未定义或为空,那么下列2句亦相等:foreach (input) push transformed, EXPR; transformed = map EXPR, input;通常,用grep来从数组里选择元素,用map来从数组里转换元素。当然,数组处理也能使用标准的循环语句来完成(foreach, for, while, until, do while, do until, redo)。(三)map用法示例1. 转换文件名为文件大小sizes = map -s $_ file_names;-s是个文件测试操作符,它返回某个文件的size。所以上面这句就返回file_names数组里每个文件的大小,结果也是个数组。2. 转换数组到hash:找到某个数组值的索引代替重复的搜索数组,我们可以用map来转换数组到hash,并通过hash关键字来进行直接查找。如下的map用法相对于重复的数组搜索,更简单高效。teams = qw(Miami Oregon Florida Tennessee Texas Oklahoma Nebraska LSU Colorado Maryland);%rank = map $teams$_, $_ + 1 0 . $#teams;print Colorado: $rankColoradon; print Texas: $rankTexas (hook em, Horns!)n; 打印结果是:Colorado: 9Texas: 5 (hook em, Horns!)上述code容易理解哦,0 .$#teams 是个列表,$#teams代表teams最后一个元素的下标值(这里是9),所以这个列表就是0-9这几个数了。map遍历上述列表,将每个列表元素临时设置为$_,并对$_在中间的里进行计算; $teams$_, $_ + 1 ,这里每次计算后返回一个2元素的列表,列表结果是某个数组值和对应的数组下标加1,明白了呀?由于对每个LIST元素进行计算时,都产生一个2元素的列表,所以总的map结果就可看作一个hash了。hash关键字就是数组元素,hash值是对应的数组下标加1。3. 转换数组到hash:查找拼错单词转换数组到hash是map的最普遍用法。在本示例里,hash的值是无关紧要的,我们仅检查hash关键字是否存在。%dictionary = map $_, 1 qw(cat dog man woman hat glove);words = qw(dog kat wimen hat man gloove);foreach $word (words) if (not $dictionary$word) print Possible misspelled word: $wordn; 打印结果是:Possible misspelled word: katPossible misspelled word: wimenPossible misspelled word: gloove看看第1句的map用法,它跟前面示例里的差不多哦。qw()这里是个列表,map对这个列表里的每个元素进行 $_, 1 计算,每次计算的结果返回一个2元素的列表,换句话说,就是%dictionary的key和value呀。所以map最终的结果就是一个hash了,关键字是qw()里的元素,值总是1,无关紧要的。然后下面的foreach语句就容易了哦,如果words里的元素不构成%dictionary的关键字的话,就打印一条出错消息。如果把%dictionary看成标准字典的话,那么就可用它来检验你自己的words字库里是否有错字了呀。4. 转换数组到hash:存储选中的CGI参数hash通常是存储传递给程序或子函数的参数的最便利的方法,而map通常是创建这个hash的最便利的方法。use CGI qw(param);%params = map $_, ( param($_) )0 grep lc($_) ne submit param();这里你可能要了解一下CGI模块的基本知识哦。param()调用返回CGI参数名的列表;param($_)调用返回指定的CGI参数名的值。假如param($_)返回某个CGI参数的多个值,那么( param($_) )0只取第一个值,以便hash仍被良好定义。上述code的意思是,将param()的结果作为输入列表,它的元素是多个CGI参数名,然后从这些参数名里grep出参数名不等于submit的,结果是一个临时列表,map的 $_, ( param($_) )0 语句再次遍历这个临时列表,并获取到参数名,和对应的参数值,将结果赋给%params。所以%params里就存储了页面提交过来的,除了submit外的其他CGI参数名和参数值(只取第1个)。很巧妙的用法,是不是?它结合用了map和grep,使code显得很简洁。(话外一句:偶在Cornell读书时,偶的师兄们很喜欢这种用法,他们往往在中间多次使用map,grep,sort进行堆叠,结果产生的code也许高效,但不容易看懂。读这样的code时,你要从右往左读,因为右边表达式产生的临时列表,是左边表达式的输入条件。)5. 产生随机密码a = (0 . 9, a . z);$password = join , map $aint rand a 0 . 7;print $passwordn;每次运行它会得到不同的结果,但长度总是8位,由0 . 7这个决定。如下是可能的输出:y2ti3dal它是个随机值,也许你能用它来做密码。这里,需要先明白几个函数,rand产生一个随机值,它后面的a其实是个标量哦,表示a数组的长度,rand a的结果可能是个小数,所以再用int函数来取整。int rand a的结果是个整数,它;=0但小于a的长度。所以$aint rand a就表示从a数组里随机取出一个字符了。0.7表示总共取8次,返回的结果再用join连接起来,就构成一个8位随机密码了呀。当然,(0 . 9, a . z)数组元素太少了,你可以修改它,使其包含大小写字符,数字和标点符号,这样密码强度就高些。6. 从数组元素里剥离数字已经说了哦,不要在EXPR里修改LIST值。如下做法是不好的:digitless = map tr/0-9/d; $_ array;它虽然从数组元素里剥离了数字,但同样破坏了该数组,:(如下做法是good:digitless = map ($x = $_) = tr/0-9/d; $x; array;它将tr的结果赋给临时变量$x,并返回$x的值,这样就保护数组了呀。7. 打印just another perl hacker,让你晕到家print map( chr (10611711511603209711011111610410111 . 4032112101114108032104097099107101114) = /./g ), n;打印的结果是:just another perl hackerchr函数将单个数字转换到相应的ASCII字符。()=/./g语法以3个数字长度为单位,分割数字串到新的串列表。比较无聊的用法,还不如用pack()和unpack(),:P8. 转置矩阵matrix = ( 1, 2, 3, 4, 5, 6, 7, 8, 9 );foreach $xyz (matrix) print $xyz-;0$xyz-;1$xyz-;2n;transposed = map $x = $_; map $matrix$_$x 0 . $#matrix ; 0 . $#$matrix0;print n;foreach $xyz (transposed) print $xyz-;0$xyz-;1$xyz-;2n;打印结果是:123456789147258369这里稍微有点复杂哦,让我们分2步看看。matrix = ( 1, 2, 3, 4, 5, 6, 7, 8, 9 );foreach $xyz (matrix) print $xyz-;0$xyz-;1$xyz-;2n;这里不难明白,( 1, 2, 3, 4, 5, 6, 7, 8, 9 ) 是个数组,它的每个元素又是个匿名数组,这样在$xyz遍历数组时,$xyz-;0,$xyz-;1,$xyz-;2就可以访问到匿名数组里的元素了。所以会打印出:123456789transposed = map $x = $_; map $matrix$_$x 0 . $#matrix ; 0 . $#$matrix0;这里复杂点,0 . $#$matrix0是个列表,$#$matrix0表示$matrix0这个匿名数组的最大下标值,0 . $#$matrix0表示矩阵的横向。$x = $_;这里将$_的值赋给$x,为什么呢?因为它后面又有个map嘛,$_的值会改变的,所以要先存储起来。外围的map返回的值是里的map计算出来的一个列表,以匿名数组形式返回。里面的map是这样的,它的输入LIST是0 . $#matrix, 表示矩阵的纵向了。$matrix$_$x这里先纵再横,就把矩阵值置换了一下。所以返回的结果列表transposed就包含置换后的矩阵了哦。是否有点糊涂?那举例看看。这样看可能好点:1, 2, 3, 4, 5, 6, 7, 8, 9外围的map遍历时,先是横向下标遍历,停留在横向0位。然后第二个map,就是纵向下标遍历了,它要遍历所有纵向下标,这样在横向0位,就先返回1,4,7的列表了,然后在横向1位,又返回2,5,8的列表,最后在横向2位,返回3,6,9的列表。还不明白呀?那偶也讲不清了,自己多想想,:P9. 查找质数:警示用法foreach $num (1 . 1000) expr = map $_ % . $_ . & 2 . int sqrt $num; if (eval grep expr 1 $num) print

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论