📄 ch05_03.htm
字号:
<HTML><HEAD><TITLE>Recipe 5.2. Testing for the Presence of a Key in a Hash (Perl Cookbook)</TITLE><METANAME="DC.title"CONTENT="Perl Cookbook"><METANAME="DC.creator"CONTENT="Tom Christiansen & Nathan Torkington"><METANAME="DC.publisher"CONTENT="O'Reilly & Associates, Inc."><METANAME="DC.date"CONTENT="1999-07-02T01:32:29Z"><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="ch05_01.htm"TITLE="5. Hashes"><LINKREL="prev"HREF="ch05_02.htm"TITLE="5.1. Adding an Element to a Hash"><LINKREL="next"HREF="ch05_04.htm"TITLE="5.3. Deleting from a Hash"></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="ch05_02.htm"TITLE="5.1. Adding an Element to a Hash"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 5.1. Adding an Element to a Hash"BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><B><FONTFACE="ARIEL,HELVETICA,HELV,SANSERIF"SIZE="-1"><ACLASS="chapter"REL="up"HREF="ch05_01.htm"TITLE="5. Hashes"></A></FONT></B></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch05_04.htm"TITLE="5.3. Deleting from a Hash"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 5.3. Deleting from a Hash"BORDER="0"></A></TD></TR></TABLE></DIV><DIVCLASS="sect1"><H2CLASS="sect1"><ACLASS="title"NAME="ch05-24827">5.2. Testing for the Presence of a Key in a Hash</A></H2><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch05-pgfId-130">Problem<ACLASS="indexterm"NAME="ch05-idx-1000006426-0"></A></A></H3><PCLASS="para">You need to know whether a hash has a particular key, regardless of any possible associated value.</P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch05-pgfId-136">Solution</A></H3><PCLASS="para">Use the <CODECLASS="literal">exists</CODE> function.</P><PRECLASS="programlisting"># does %HASH have a value for $KEY ?if (exists($HASH{$KEY})) { # it exists} else { # it doesn't}</PRE></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch05-pgfId-154">Discussion</A></H3><PCLASS="para">This code uses <CODECLASS="literal">exists</CODE> to check whether a key is in the <CODECLASS="literal">%food_color</CODE> hash:</P><PRECLASS="programlisting"># %food_color per the introductionforeach $name ("Banana", "Martini") { if (exists $food_color{$name}) { print "$name is a food.\n"; } else { print "$name is a drink.\n"; }}<CODECLASS="userinput"><B><CODECLASS="replaceable"><I>Banana is a food.</I></CODE></B></CODE><CODECLASS="userinput"><B><CODECLASS="replaceable"><I>Martini is a drink.</I></CODE></B></CODE></PRE><PCLASS="para">The <CODECLASS="literal">exists</CODE> function tests whether a key is in the hash. It doesn't test whether the value corresponding to that key is defined, nor whether the value is true or false. We may be splitting hairs, but problems caused by confusing existence, definedness, and truth can multiply like rabbits. Take this code:</P><PRECLASS="programlisting">%age = ();$age{"Toddler"} = 3;$age{"Unborn"} = 0;$age{"Phantasm"} = undef;foreach $thing ("Toddler", "Unborn", "Phantasm", "Relic") { print "$thing: "; print "Exists " if exists $age{$thing}; print "Defined " if defined $age{$thing}; print "True " if $age{$thing}; print "\n";}<CODECLASS="userinput"><B><CODECLASS="replaceable"><I>Toddler: Exists Defined True </I></CODE></B></CODE><CODECLASS="userinput"><B><CODECLASS="replaceable"><I>Unborn: Exists Defined </I></CODE></B></CODE><CODECLASS="userinput"><B><CODECLASS="replaceable"><I>Phantasm: Exists </I></CODE></B></CODE><CODECLASS="userinput"><B><CODECLASS="replaceable"><I>Relic: </I></CODE></B></CODE></PRE><PCLASS="para"><CODECLASS="literal">$age{"Toddler"}</CODE> passes the existence, definedness, and truth tests. It exists because we gave <CODECLASS="literal">"Toddler"</CODE> a value in the hash, it's defined because that value isn't <CODECLASS="literal">undef</CODE>, and it's true because the value isn't one of Perl's false values.</P><PCLASS="para"><CODECLASS="literal">$age{"Unborn"}</CODE> passes only the existence and definedness tests. It exists because we gave <CODECLASS="literal">"Unborn"</CODE> a value in the hash, and it's defined because that value isn't <CODECLASS="literal">undef</CODE>. It isn't <EMCLASS="emphasis">true</EM>, however, because <CODECLASS="literal">0</CODE> is one of Perl's false values.</P><PCLASS="para"><CODECLASS="literal">$age{"Phantasm"}</CODE> passes only the existence test. It exists because we gave <CODECLASS="literal">"Phantasm"</CODE> a value in the hash. Because that value was <CODECLASS="literal">undef</CODE>, it doesn't pass the definedness test. Because <CODECLASS="literal">undef</CODE> is also one of Perl's false values, it doesn't pass the truth test either.</P><PCLASS="para"><CODECLASS="literal">$age{"Relic"}</CODE> passes none of the tests. We didn't put a value for <CODECLASS="literal">"Relic"</CODE> into the hash, so the existence test fails. Because we didn't put a value in, <CODECLASS="literal">$age{"Relic"}</CODE> is <CODECLASS="literal">undef</CODE> whenever we try to access it. We know from <CODECLASS="literal">"Phantasm"</CODE> that <CODECLASS="literal">undef</CODE> fails the definedness and truth tests.</P><PCLASS="para">Sometimes it's useful to store <CODECLASS="literal">undef</CODE> in a hash. This indicates "I've seen this key, but it didn't have a meaningful value associated with it." Take, for instance, a program to look up file sizes given a list of files as input. This version tries to skip files we've seen before, but it doesn't skip zero-length files, and it doesn't skip files that we've seen before but don't exist.</P><PRECLASS="programlisting">%size = ();while (<>) { chomp; next if $size{$_}; # WRONG attempt to skip $size{$_} = -s $_;}</PRE><PCLASS="para">If we change the incorrect line to call <CODECLASS="literal">exists</CODE>, we also skip files that couldn't be <CODECLASS="literal">stat</CODE>ted, instead of repeatedly trying (and failing) to look them up:</P><PRECLASS="programlisting"> next if exists $size{$_};</PRE><PCLASS="para">The food and drink code above assumes that which is not food must be a drink. This is a dangerous assumption to make in the real world.</P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch05-pgfId-250">See Also</A></H3><PCLASS="para">The <CODECLASS="literal">exists</CODE> and <CODECLASS="literal">defined</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>; the discussion of truth in the "Scalar Values" section of <ICLASS="filename">perldata </I>(1), and the <ACLASS="olink"HREF="../prog/ch02_03.htm#PERL2-CH-2-SECT-3.3.2">"Boolean Context"</A> section of <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="indexterm"NAME="ch05-idx-1000006425-0"></A><ACLASS="indexterm"NAME="ch05-idx-1000006425-1"></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="ch05_02.htm"TITLE="5.1. Adding an Element to a Hash"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 5.1. Adding an Element to a Hash"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="ch05_04.htm"TITLE="5.3. Deleting from a Hash"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 5.3. Deleting from a Hash"BORDER="0"></A></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228">5.1. Adding an Element to a Hash</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">5.3. Deleting from a Hash</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 + -