📄 ch04_16.htm
字号:
CLASS="programlisting">@sorted = map { $_->[1] } sort { $a->[0] <=> $b->[0] } map { [ length $_, $_ ] } @strings;</PRE><PCLASS="para">The operations now appear in reverse order. When you meet a <CODECLASS="literal">map</CODE>-<CODECLASS="literal">sort</CODE>-<CODECLASS="literal">map</CODE>, you should read it from the bottom up to determine the function:</P><DLCLASS="variablelist"><DTCLASS="term"><CODECLASS="literal">@strings</CODE> </DT><DDCLASS="listitem"><PCLASS="para">The last part is the data to be sorted. Here it's just an array, but later we'll see that this can be a subroutine or even backticks. Anything that returns a list to be sorted is fair game.</P></DD><DTCLASS="term"><CODECLASS="literal">map</CODE> </DT><DDCLASS="listitem"><PCLASS="para">The <CODECLASS="literal">map</CODE> closest to the bottom builds the temporary list of anonymous arrays. This list contains the precomputed fields (<CODECLASS="literal">length</CODE> <CODECLASS="literal">$_ </CODE>) and also records the original element (<CODECLASS="literal">$_ </CODE>) by storing them both in an anonymous array. Look at this <CODECLASS="literal">map</CODE> line to find out how the fields are computed.</P></DD><DTCLASS="term"><CODECLASS="literal">sort</CODE> </DT><DDCLASS="listitem"><PCLASS="para">The <CODECLASS="literal">sort</CODE> line sorts the list of anonymous arrays by comparing the precomputed fields. It won't tell you much, other than whether the list is sorted in ascending or descending order.</P></DD><DTCLASS="term"><CODECLASS="literal">map</CODE> </DT><DDCLASS="listitem"><PCLASS="para">The <CODECLASS="literal">map</CODE> at the top of the statement turns the sorted list of anonymous arrays back into a list of the sorted original elements. It will generally be the same for every <CODECLASS="literal">map</CODE>-<CODECLASS="literal">sort</CODE>-<CODECLASS="literal">map</CODE>.</P></DD></DL><PCLASS="para">Here's a more complicated example, which sorts by the first number that appears on each line in <CODECLASS="literal">@fields</CODE>:</P><PRECLASS="programlisting">@temp = map { [ /(\d+)/, $_ ] } @fields;@sorted_temp = sort { $a->[0] <=> $b->[0] } @temp;@sorted_fields = map { $_->[1] } @sorted_temp;</PRE><PCLASS="para">The regular expression mumbo-jumbo in the first line extracts the first number from the line being processed by <CODECLASS="literal">map</CODE>. We use the regular expression <CODECLASS="literal">/(\d+)/</CODE> in a list context to extract the number.</P><PCLASS="para">We can remove the temporary arrays in that code, giving us:</P><PRECLASS="programlisting">@sorted_fields = map { $_->[1] } sort { $a->[0] <=> $b->[0] } map { [ /(\d+)/, $_ ] } @fields;</PRE><PCLASS="para">This final example compactly sorts colon-separated data, as from Unix's <EMCLASS="emphasis">passwd</EM> file. It sorts the file numerically by fourth field (group id), then numerically by the third field (user id), and then alphabetically by the first field (user name).</P><PRECLASS="programlisting">print map { $_->[0] } # whole line sort { $a->[1] <=> $b->[1] # gid || $a->[2] <=> $b->[2] # uid || $a->[3] cmp $b->[3] # login } map { [ $_, (split /:/)[3,2,0] ] } `cat /etc/passwd`;</PRE><PCLASS="para">This compact, <CODECLASS="literal">map</CODE>-<CODECLASS="literal">sort</CODE>-<CODECLASS="literal">map</CODE> technique is more reminiscent of the functional world of Lisp and Scheme programming than Perl's normal C and <EMCLASS="emphasis">awk</EM> heritage. Because it was first pointed out by Randal <ACLASS="indexterm"NAME="ch04-idx-1000006804-0"></A>Schwartz, this black art is often referred to as the <ICLASS="firstterm">Schwartzian Transform</I>.</P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch04-pgfId-1569">See Also</A></H3><PCLASS="para">The <CODECLASS="literal">sort</CODE> function in <ICLASS="filename">perlfunc </I>(1) and <ACLASS="olink"HREF="../prog/ch03_01.htm">Chapter 3</A> of <ACLASS="citetitle"HREF="../prog/index.htm"TITLE="Programming Perl"><CITECLASS="citetitle">Programming Perl</CITE></A>; the <CODECLASS="literal">cmp</CODE> and <CODECLASS="literal"><=></CODE> operators in <ICLASS="filename">perlop </I>(1) and <ACLASS="olink"HREF="../prog/ch02_01.htm">Chapter 2</A> of <ACLASS="citetitle"HREF="../prog/index.htm"TITLE="Programming Perl"><CITECLASS="citetitle">Programming Perl</CITE></A>; <ACLASS="xref"HREF="ch04_15.htm"TITLE="Sorting an Array Numerically">Recipe 4.14</A><ACLASS="indexterm"NAME="ch04-idx-1000006760-0"></A><ACLASS="indexterm"NAME="ch04-idx-1000006760-1"></A><ACLASS="indexterm"NAME="ch04-idx-1000006760-2"></A><ACLASS="indexterm"NAME="ch04-idx-1000006760-3"></A></P></DIV></DIV><DIVCLASS="htmlnav"><P></P><HRALIGN="LEFT"WIDTH="684"TITLE="footer"><TABLEWIDTH="684"BORDER="0"CELLSPACING="0"CELLPADDING="0"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch04_15.htm"TITLE="4.14. Sorting an Array Numerically"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 4.14. Sorting an Array Numerically"BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><ACLASS="book"HREF="index.htm"TITLE="Perl Cookbook"><IMGSRC="../gifs/txthome.gif"ALT="Perl Cookbook"BORDER="0"></A></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch04_17.htm"TITLE="4.16. Implementing a Circular List"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 4.16. Implementing a Circular List"BORDER="0"></A></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228">4.14. Sorting an Array Numerically</TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><ACLASS="index"HREF="index/index.htm"TITLE="Book Index"><IMGSRC="../gifs/index.gif"ALT="Book Index"BORDER="0"></A></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228">4.16. Implementing a Circular List</TD></TR></TABLE><HRALIGN="LEFT"WIDTH="684"TITLE="footer"><FONTSIZE="-1"></DIV<!-- LIBRARY NAV BAR --> <img src="../gifs/smnavbar.gif" usemap="#library-map" border="0" alt="Library Navigation Links"><p> <a href="copyrght.htm">Copyright © 2002</a> O'Reilly & Associates. All rights reserved.</font> </p> <map name="library-map"> <area shape="rect" coords="1,0,85,94" href="../index.htm"><area shape="rect" coords="86,1,178,103" href="../lwp/index.htm"><area shape="rect" coords="180,0,265,103" href="../lperl/index.htm"><area shape="rect" coords="267,0,353,105" href="../perlnut/index.htm"><area shape="rect" coords="354,1,446,115" href="../prog/index.htm"><area shape="rect" coords="448,0,526,132" href="../tk/index.htm"><area shape="rect" coords="528,1,615,119" href="../cookbook/index.htm"><area shape="rect" coords="617,0,690,135" href="../pxml/index.htm"></map> </BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -