⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch04_15.htm

📁 By Tom Christiansen and Nathan Torkington ISBN 1-56592-243-3 First Edition, published August 1998
💻 HTM
字号:
<HTML><HEAD><TITLE>Recipe 4.14. Sorting an Array Numerically (Perl Cookbook)</TITLE><METANAME="DC.title"CONTENT="Perl Cookbook"><METANAME="DC.creator"CONTENT="Tom Christiansen &amp; Nathan Torkington"><METANAME="DC.publisher"CONTENT="O'Reilly &amp; Associates, Inc."><METANAME="DC.date"CONTENT="1999-07-02T01:32:03Z"><METANAME="DC.type"CONTENT="Text.Monograph"><METANAME="DC.format"CONTENT="text/html"SCHEME="MIME"><METANAME="DC.source"CONTENT="1-56592-243-3"SCHEME="ISBN"><METANAME="DC.language"CONTENT="en-US"><METANAME="generator"CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"><LINKREV="made"HREF="mailto:online-books@oreilly.com"TITLE="Online Books Comments"><LINKREL="up"HREF="ch04_01.htm"TITLE="4. Arrays"><LINKREL="prev"HREF="ch04_14.htm"TITLE="4.13. Finding All Elements in an Array Matching Certain Criteria"><LINKREL="next"HREF="ch04_16.htm"TITLE="4.15. Sorting a List by Computable Field"></HEAD><BODYBGCOLOR="#FFFFFF"><img alt="Book Home" border="0" src="gifs/smbanner.gif" usemap="#banner-map" /><map name="banner-map"><area shape="rect" coords="1,-2,616,66" href="index.htm" alt="Perl Cookbook"><area shape="rect" coords="629,-11,726,25" href="jobjects/fsearch.htm" alt="Search this book" /></map><div class="navbar"><p><TABLEWIDTH="684"BORDER="0"CELLSPACING="0"CELLPADDING="0"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch04_14.htm"TITLE="4.13. Finding All Elements in an Array Matching Certain Criteria"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 4.13. Finding All Elements in an Array Matching Certain Criteria"BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><B><FONTFACE="ARIEL,HELVETICA,HELV,SANSERIF"SIZE="-1"><ACLASS="chapter"REL="up"HREF="ch04_01.htm"TITLE="4. Arrays"></A></FONT></B></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch04_16.htm"TITLE="4.15. Sorting a List by Computable Field"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 4.15. Sorting a List by Computable Field"BORDER="0"></A></TD></TR></TABLE></DIV><DIVCLASS="sect1"><H2CLASS="sect1"><ACLASS="title"NAME="ch04-36797">4.14. Sorting an Array Numerically</A></H2><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch04-pgfId-1197">Problem <ACLASS="indexterm"NAME="ch04-idx-1000006739-0"></A><ACLASS="indexterm"NAME="ch04-idx-1000006739-1"></A></A></H3><PCLASS="para">You want to sort a list of numbers, but Perl's <CODECLASS="literal">sort</CODE> (by default) sorts alphabetically in ASCII order.</P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch04-pgfId-1205">Solution</A></H3><PCLASS="para">Use Perl's <ACLASS="indexterm"NAME="ch04-idx-1000006745-0"></A><ACLASS="indexterm"NAME="ch04-idx-1000006745-1"></A><ACLASS="indexterm"NAME="ch04-idx-1000006745-2"></A><CODECLASS="literal">sort</CODE> function and the &lt;=&gt; numerical comparison operator:</P><PRECLASS="programlisting">@sorted = sort { $a &lt;=&gt; $b } @unsorted;</PRE></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch04-pgfId-1215">Discussion</A></H3><PCLASS="para">The <CODECLASS="literal">sort</CODE> function takes an optional code block, which lets you replace the default alphabetic comparison subroutine with your own. This comparison function is called each time <CODECLASS="literal">sort</CODE> has to compare two values. The values to compare are loaded into the special package variables <CODECLASS="literal">$a</CODE> and <CODECLASS="literal">$b</CODE>, which are automatically <CODECLASS="literal">local</CODE>ized.</P><PCLASS="para">The comparison function should return a negative number if <CODECLASS="literal">$a</CODE> ought to appear before <CODECLASS="literal">$b</CODE> in the output list, <CODECLASS="literal">0</CODE> if they're the same and their order doesn't matter, or a positive number if <CODECLASS="literal">$a</CODE> ought to appear after <CODECLASS="literal">$b</CODE>. Perl has two operators that behave this way: &lt;=&gt; for sorting numbers in ascending numeric order, and <CODECLASS="literal">cmp</CODE><ACLASS="indexterm"NAME="ch04-idx-1000006753-0"></A> for sorting strings in ascending alphabetic order. By default, <CODECLASS="literal">sort</CODE> uses <CODECLASS="literal">cmp</CODE>-style comparisons.</P><PCLASS="para">Here's code that sorts the list of PIDs in <CODECLASS="literal">@pids</CODE>, lets the user select one, then sends it a TERM signal followed by a KILL signal. We use a code block that compares <CODECLASS="literal">$a</CODE> to <CODECLASS="literal">$b</CODE> with &lt;=&gt; to sort numerically:</P><PRECLASS="programlisting"># @pids is an unsorted array of process IDsforeach my $pid (sort { $a &lt;=&gt; $b } @pids) {    print &quot;$pid\n&quot;;}print &quot;Select a process ID to kill:\n&quot;;chomp ($pid = &lt;&gt;);die &quot;Exiting ... \n&quot; unless $pid &amp;&amp; $pid =~ /^\d+$/;kill('TERM',$pid);sleep 2;kill('KILL',$pid);</PRE><PCLASS="para">If you use <CODECLASS="literal">$a</CODE> <CODECLASS="literal">&lt;=&gt;</CODE> <CODECLASS="literal">$b</CODE> or <CODECLASS="literal">$a</CODE> <CODECLASS="literal">cmp</CODE> <CODECLASS="literal">$b</CODE>, the list will be sorted in ascending order. For a descending sort, all we have to do is swap <CODECLASS="literal">$a</CODE> and <CODECLASS="literal">$b</CODE> in the sort subroutine:</P><PRECLASS="programlisting">@descending = sort { $b &lt;=&gt; $a } @unsorted;</PRE><PCLASS="para">Comparison routines must be consistent; that is, they should always return the same answer when called with the same values. Inconsistent comparison routines lead to infinite loops or core dumps, especially in older releases of Perl.</P><PCLASS="para">You can also say <CODECLASS="literal">sort</CODE> <CODECLASS="literal">SUBNAME</CODE> <CODECLASS="literal">LIST</CODE> where <CODECLASS="literal">SUBNAME</CODE> is the name of a comparison subroutine returning <CODECLASS="literal">-1</CODE>, <CODECLASS="literal">0</CODE>, or <CODECLASS="literal">+1</CODE>. In the interests of speed, the normal calling conventions are bypassed, and the values to be compared magically appear for the duration of the subroutine in the global package variables <CODECLASS="literal">$a</CODE> and <CODECLASS="literal">$b</CODE>. Because of the odd way Perl calls this subroutine, it may not be recursive.</P><PCLASS="para">A word of warning: <CODECLASS="literal">$a</CODE> and <CODECLASS="literal">$b</CODE> are set in the package active in the call to <CODECLASS="literal">sort</CODE>, which may not be the same as the one that the <CODECLASS="literal">SUBNAME</CODE> function passed to <CODECLASS="literal">sort</CODE> was compiled in! For example:</P><PRECLASS="programlisting">package Sort_Subs;sub revnum { $b &lt;=&gt; $a }package Other_Pack;@all = sort Sort_Subs::revnum 4, 19, 8, 3;</PRE><PCLASS="para">This will silently fail (unless you have <BCLASS="emphasis.bold">-w</B> in effect, in which case it will vocally fail), because the <CODECLASS="literal">sort</CODE> call sets the package variables <CODECLASS="literal">$a</CODE> and <CODECLASS="literal">$b</CODE> in its own package, Other_Pack, but the <CODECLASS="literal">revnum</CODE> function uses its own package's versions. This is another reason why in-lining sort functions is easier, as in:</P><PRECLASS="programlisting">@all = sort { $b &lt;=&gt; $a } 4, 19, 8, 3;</PRE><PCLASS="para">For more on packages, see <ACLASS="xref"HREF="ch10_01.htm"TITLE="Subroutines">Chapter 10, <CITECLASS="chapter">Subroutines</CITE></A>.</P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch04-pgfId-1287">See Also</A></H3><PCLASS="para">The <CODECLASS="literal">cmp</CODE> and &lt;=&gt; operators in <EMCLASS="emphasis">perlop </EM>(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>; the <CODECLASS="literal">kill</CODE>, <CODECLASS="literal">sort</CODE>, and <CODECLASS="literal">sleep</CODE> functions 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><ACLASS="indexterm"NAME="ch04-idx-1000007479-0"></A><ACLASS="indexterm"NAME="ch04-idx-1000007479-1"></A><ACLASS="indexterm"NAME="ch04-idx-1000007479-2"></A>; <ACLASS="xref"HREF="ch04_16.htm"TITLE="Sorting a List by Computable Field">Recipe 4.15</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_14.htm"TITLE="4.13. Finding All Elements in an Array Matching Certain Criteria"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 4.13. Finding All Elements in an Array Matching Certain Criteria"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_16.htm"TITLE="4.15. Sorting a List by Computable Field"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 4.15. Sorting a List by Computable Field"BORDER="0"></A></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228">4.13. Finding All Elements in an Array Matching Certain Criteria</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.15. Sorting a List by Computable Field</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 &copy; 2002</a> O'Reilly &amp; 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 + -