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

📄 perlfaq4.html

📁 《Perl 5教程》及《perl常问问题集》
💻 HTML
📖 第 1 页 / 共 4 页
字号:
<HR><H3><A NAME="How_do_I_look_up_a_hash_element_">How do I look up a hash element by value?</A></H3>Create a reverse hash:<P><PRE>    %by_value = reverse %by_key;    $key = $by_value{$value};</PRE><P>That's not particularly efficient. It would be more space-efficient to use:<P><PRE>    while (($key, $value) = each %by_key) {        $by_value{$value} = $key;    }</PRE><P>If your hash could have repeated values, the methods above will only findone of the associated keys. This may or may not worry you.<P><P><HR><H3><A NAME="How_can_I_know_how_many_entries_">How can I know how many entries are in a hash?</A></H3>If you mean how many keys, then all you have to do is take the scalar senseof the <CODE>keys()</CODE> function:<P><PRE>    $num_keys = scalar keys %hash;</PRE><P>In void context it just resets the iterator, which is faster for tiedhashes.<P><P><HR><H3><A NAME="How_do_I_sort_a_hash_optionally">How do I sort a hash (optionally by value instead of key)?</A></H3>Internally, hashes are stored in a way that prevents you from imposing anorder on key-value pairs. Instead, you have to sort a list of the keys orvalues:<P><PRE>    @keys = sort keys %hash;    # sorted by key    @keys = sort {                    $hash{$a} cmp $hash{$b}            } keys %hash;       # and by value</PRE><P>Here we'll do a reverse numeric sort by value, and if two keys are identical, sort by length of key, and if that fails, by straight <FONT SIZE=-1>ASCII</FONT> comparison of the keys (well, possibly modified by your locale -- see<A HREF="../../tppmsgs/msgs1.htm#105" tppabs="http://www.perl.org/CPAN/doc/manual/html/pod/perllocale.html">the perllocale manpage</A>).<P><PRE>    @keys = sort {                $hash{$b} &lt;=&gt; $hash{$a}                          ||                length($b) &lt;=&gt; length($a)                          ||                      $a cmp $b    } keys %hash;</PRE><P><P><HR><H3><A NAME="How_can_I_always_keep_my_hash_so">How can I always keep my hash sorted?</A></H3>You can look into using the DB_File module and <CODE>tie()</CODE> using the<CODE>$DB_BTREE</CODE> hash bindings as documented in <A HREF="../../tppmsgs/msgs1.htm#108" tppabs="http://www.perl.org/CPAN/doc/manual/html/lib/DB_File.html#In_Memory_Databases">In Memory Databases</A>.<P><P><HR><H3><A NAME="What_s_the_difference_between_d">What's the difference between "delete" and "undef" with hashes?</A></H3>Hashes are pairs of scalars: the first is the key, the second is the value.The key will be coerced to a string, although the value can be any kind ofscalar: string, number, or reference. If a key <CODE>$key</CODE> is present in the array, <CODE>exists($key)</CODE> will return true. The value for a given key can be <CODE>undef</CODE>, in which case <CODE>$array{$key}</CODE> will be<CODE>undef</CODE> while <CODE>$exists{$key}</CODE> will return true. This corresponds to (<CODE>$key</CODE>, <CODE>undef</CODE>) being in the hash.<P>Pictures help... here's the <CODE>%ary</CODE> table:<P><PRE>          keys  values        +------+------+        |  a   |  3   |        |  x   |  7   |        |  d   |  0   |        |  e   |  2   |        +------+------+</PRE><P>And these conditions hold<P><PRE>        $ary{'a'}                       is true        $ary{'d'}                       is false        defined $ary{'d'}               is true        defined $ary{'a'}               is true        exists $ary{'a'}                is true (perl5 only)        grep ($_ eq 'a', keys %ary)     is true</PRE><P>If you now say<P><PRE>        undef $ary{'a'}</PRE><P>your table now reads:<P><PRE>          keys  values        +------+------+        |  a   | undef|        |  x   |  7   |        |  d   |  0   |        |  e   |  2   |        +------+------+</PRE><P>and these conditions now hold; changes in caps:<P><PRE>        $ary{'a'}                       is FALSE        $ary{'d'}                       is false        defined $ary{'d'}               is true        defined $ary{'a'}               is FALSE        exists $ary{'a'}                is true (perl5 only)        grep ($_ eq 'a', keys %ary)     is true</PRE><P>Notice the last two: you have an undef value, but a defined key!<P>Now, consider this:<P><PRE>        delete $ary{'a'}</PRE><P>your table now reads:<P><PRE>          keys  values        +------+------+        |  x   |  7   |        |  d   |  0   |        |  e   |  2   |        +------+------+</PRE><P>and these conditions now hold; changes in caps:<P><PRE>        $ary{'a'}                       is false        $ary{'d'}                       is false        defined $ary{'d'}               is true        defined $ary{'a'}               is false        exists $ary{'a'}                is FALSE (perl5 only)        grep ($_ eq 'a', keys %ary)     is FALSE</PRE><P>See, the whole entry is gone!<P><P><HR><H3><A NAME="Why_don_t_my_tied_hashes_make_th">Why don't my tied hashes make the defined/exists distinction?</A></H3>They may or may not implement the <CODE>EXISTS()</CODE> and <CODE>DEFINED()</CODE> methods differently. For example, there isn't the concept of undef with hashes that are tied to <FONT SIZE=-1>DBM*</FONT> files. This means the true/false tables above will give different results when used on such a hash. It also means that exists and defined do the same thing with a <FONT SIZE=-1>DBM*</FONT> file, and what they end up doing is not what they do with ordinary hashes.<P><P><HR><H3><A NAME="How_do_I_reset_an_each_operati">How do I reset an each() operation part-way through?</A></H3>Using <CODE>keys %hash</CODE> in a scalar context returns the number of keys in the hash <EM>and</EM> resets the iterator associated with the hash. You may need to do this ifyou use <CODE>last</CODE> to exit a loop early so that when you re-enter it, the hash iterator hasbeen reset.<P><P><HR><H3><A NAME="How_can_I_get_the_unique_keys_fr">How can I get the unique keys from two hashes?</A></H3>First you extract the keys from the hashes into arrays, and then solve theuniquifying the array problem described above. For example:<P><PRE>    %seen = ();    for $element (keys(%foo), keys(%bar)) {        $seen{$element}++;    }    @uniq = keys %seen;</PRE><P>Or more succinctly:<P><PRE>    @uniq = keys %{{%foo,%bar}};</PRE><P>Or if you really want to save space:<P><PRE>    %seen = ();    while (defined ($key = each %foo)) {        $seen{$key}++;    }    while (defined ($key = each %bar)) {        $seen{$key}++;    }    @uniq = keys %seen;</PRE><P><P><HR><H3><A NAME="How_can_I_store_a_multidimension">How can I store a multidimensional array in a DBM file?</A></H3>Either stringify the structure yourself (no fun), or else get the <FONT SIZE=-1>MLDBM</FONT> (which uses Data::Dumper) module from <FONT SIZE=-1>CPAN</FONT> and layer it on top of either DB_File or GDBM_File.<P><P><HR><H3><A NAME="How_can_I_make_my_hash_remember_">How can I make my hash remember the order I put elements into it?</A></H3>Use the Tie::IxHash from <FONT SIZE=-1>CPAN.</FONT><P><PRE>    use Tie::IxHash;    tie(%myhash, Tie::IxHash);    for ($i=0; $i&lt;20; $i++) {        $myhash{$i} = 2*$i;    }    @keys = keys %myhash;    # @keys = (0,1,2,3,...)</PRE><P><P><HR><H3><A NAME="Why_does_passing_a_subroutine_an">Why does passing a subroutine an undefined element in a hash create it?</A></H3>If you say something like:<P><PRE>    somefunc($hash{&quot;nonesuch key here&quot;});</PRE><P>Then that element ``autovivifies''; that is, it springs into existencewhether you store something there or not. That's because functions getscalars passed in by reference. If <CODE>somefunc()</CODE> modifies <CODE>$_[0]</CODE>, it has to be ready to write it back into the caller's version.<P>This has been fixed as of perl5.004.<P>Normally, merely accessing a key's value for a nonexistent key does<EM>not</EM> cause that key to be forever there. This is different than awk's behavior.<P><P><HR><H3><A NAME="How_can_I_make_the_Perl_equivale">How can I make the Perl equivalent of a C structure/C++ class/hash or array of hashes or arrays?</A></H3>Use references (documented in <A HREF="../../tppmsgs/msgs0.htm#59" tppabs="http://www.perl.org/CPAN/doc/manual/html/pod/perlref.html">the perlref manpage</A>). Examples of complex data structures are given in <A HREF="../../tppmsgs/msgs0.htm#64" tppabs="http://www.perl.org/CPAN/doc/manual/html/pod/perldsc.html">the perldsc manpage</A> and <A HREF="../../tppmsgs/msgs0.htm#63" tppabs="http://www.perl.org/CPAN/doc/manual/html/pod/perllol.html">the perllol manpage</A>. Examples of structures and object-oriented classes are in <A HREF="../../tppmsgs/msgs0.htm#57" tppabs="http://www.perl.org/CPAN/doc/manual/html/pod/perltoot.html">the perltoot manpage</A>.<P><P><HR><H3><A NAME="How_can_I_use_a_reference_as_a_h">How can I use a reference as a hash key?</A></H3>You can't do this directly, but you could use the standard Tie::Refhashmodule distributed with perl.<P><P><HR><H2><A NAME="Data_Misc">Data: Misc</A></H2><P><HR><H3><A NAME="How_do_I_handle_binary_data_corr">How do I handle binary data correctly?</A></H3>Perl is binary clean, so this shouldn't be a problem. For example, thisworks fine (assuming the files are found):<P><PRE>    if (`cat /vmunix` =~ /gzip/) {        print &quot;Your kernel is GNU-zip enabled!\n&quot;;    }</PRE><P>On some systems, however, you have to play tedious games with ``text''versus ``binary'' files. See <A HREF="../../tppmsgs/msgs0.htm#68" tppabs="http://www.perl.org/CPAN/doc/manual/html/pod/perlfunc.html#binmode">binmode</A>.<P>If you're concerned about 8-bit <FONT SIZE=-1>ASCII</FONT> data, then see <A HREF="../../tppmsgs/msgs1.htm#105" tppabs="http://www.perl.org/CPAN/doc/manual/html/pod/perllocale.html">the perllocale manpage</A>.<P>If you want to deal with multibyte characters, however, there are somegotchas. See the section on Regular Expressions.<P><P><HR><H3><A NAME="How_do_I_determine_whether_a_sca">How do I determine whether a scalar is a number/whole/integer/float?</A></H3>Assuming that you don't care about <FONT SIZE=-1>IEEE</FONT> notations like ``NaN'' or ``Infinity'', youprobably just want to use a regular expression.<P><PRE>   warn &quot;has nondigits&quot;        if     /\D/;   warn &quot;not a whole number&quot;   unless /^\d+$/;   warn &quot;not an integer&quot;       unless /^-?\d+$/;  # reject +3   warn &quot;not an integer&quot;       unless /^[+-]?\d+$/;   warn &quot;not a decimal number&quot; unless /^-?\d+\.?\d*$/;  # rejects .2   warn &quot;not a decimal number&quot; unless /^-?(?:\d+(?:\.\d*)?|\.\d+)$/;   warn &quot;not a C float&quot;       unless /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/;</PRE><P>Or you could check out <A HREF="../../tppmsgs/msgs1.htm#137" tppabs="http://www.perl.com/CPAN/modules/by-module/String/String-Scanf-1.1.tar.gz">http://www.perl.com/CPAN/modules/by-module/String/String-Scanf-1.1.tar.gz</A> instead. The <FONT SIZE=-1>POSIX</FONT> module (part of the standard Perl distribution) provides the <CODE>strtol</CODE> and <CODE>strtod</CODE> for converting strings to double and longs, respectively.<P><P><HR><H3><A NAME="How_do_I_keep_persistent_data_ac">How do I keep persistent data across program calls?</A></H3>For some specific applications, you can use one of the <FONT SIZE=-1>DBM</FONT> modules. See <A HREF="../../tppmsgs/msgs1.htm#138" tppabs="http://www.perl.org/CPAN/doc/manual/html/lib/AnyDBM_File.html">the AnyDBM_File manpage</A>. More generically, you should consult the FreezeThaw, Storable, or Class::Eroot modules from <FONT SIZE=-1>CPAN.</FONT><P><P><HR><H3><A NAME="How_do_I_print_out_or_copy_a_rec">How do I print out or copy a recursive data structure?</A></H3>The Data::Dumper module on <FONT SIZE=-1>CPAN</FONT> is nice for printing out data structures, andFreezeThaw for copying them. For example:<P><PRE>    use FreezeThaw qw(freeze thaw);    $new = thaw freeze $old;</PRE><P>Where <CODE>$old</CODE> can be (a reference to) any kind of data structureyou'd like. It will be deeply copied.<P><P><HR><H3><A NAME="How_do_I_define_methods_for_ever">How do I define methods for every class/object?</A></H3>Use the <FONT SIZE=-1>UNIVERSAL</FONT> class (see <A HREF="../../tppmsgs/msgs1.htm#139" tppabs="http://www.perl.org/CPAN/doc/manual/html/lib/UNIVERSAL.html">the UNIVERSAL manpage</A>).<P><P><HR><H3><A NAME="How_do_I_verify_a_credit_card_ch">How do I verify a credit card checksum?</A></H3>Get the Business::CreditCard module from <FONT SIZE=-1>CPAN.</FONT><P><P><HR><H2><A NAME="AUTHOR_AND_COPYRIGHT">AUTHOR AND COPYRIGHT</A></H2>Copyright (c) 1997 Tom Christiansen and Nathan Torkington. All rightsreserved. See <A HREF="perlfaq.html" tppabs="http://202.96.217.5/~xiaoyi/perlfaq.html">the perlfaq manpage</A> for distribution information.<P></DL>    </BODY>    </HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -