alphabetical subset of hash keys 
Author Message
 alphabetical subset of hash keys

If I have a large hash, how can I run a routine on just the keys that
start with a certain letter? I want something that looks like:

    foreach $key (keysthatstartwithA %myhash) {
        print "$myhash{$key}\n";
    }

to work like:

    foreach $key (keys %myhash) {
        if ( substr($key,0,1)=="A" ) { print "$myhash{$key}\n" };
    }

but without having to bang through every key in the hash to see if it
starts with 'A' (that just seems inefficient to me)

BTW - this hash is tied to a BTREE Berkely DB, so the hash keys will
be returned in alphabetical order. What I'm trying to do is allow the
user to 'query' the database by letter.

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  John L Capell    (remove "SpamMeNot" from reply-to eMail)  ???
  Montgomery, Alabama
     =-=-=-=-=-=-=
  http://www.*-*-*.com/
    " Changing the way Montgomery Surfs the 'NET "
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=



Fri, 30 Jun 2000 03:00:00 GMT  
 alphabetical subset of hash keys

: If I have a large hash, how can I run a routine on just the keys that
: start with a certain letter? I want something that looks like:

:     foreach $key (keysthatstartwithA %myhash) {
:         print "$myhash{$key}\n";
:     }

     foreach $key (grep /^A/, keys %myhash) {
         print "$myhash{$key}\n";
     }

But that still "bangs through every key in the hash", it's just
that grep() does the banging for you...

--
    Tad McClellan                          SGML Consulting

    Fort Worth, Texas



Fri, 30 Jun 2000 03:00:00 GMT  
 alphabetical subset of hash keys



: If I have a large hash, how can I run a routine on just the keys that
: start with a certain letter?
[snip]
:     foreach $key (keys %myhash) {
:         if ( substr($key,0,1)=="A" ) { print "$myhash{$key}\n" };
:     }
:
: but without having to bang through every key in the hash to see if it
: starts with 'A' (that just seems inefficient to me)

In terms of efficiency, unpack is probably a better choice than substr,
e.g.

    foreach $key (keys %hash) {
        ## use the eq (not ==) operator for string comparison
        ##                            VV
        next unless unpack("A", $key) eq "A";

        ...;
    }

Still, this is a microoptimization, and not likely to produce huge
savings (unless you're dealing with very large hashes in terms of the
number of keys).  Greater efficiency will probably come from a change
in your general approach to your data (read: algorithm).

: BTW - this hash is tied to a BTREE Berkely DB, so the hash keys will
: be returned in alphabetical order. What I'm trying to do is allow the
: user to 'query' the database by letter.

I don't know what you're using these data for, but would it help to
organize your data into separate hashes (say, a hash for each letter
of the alphabet)?

:   John L Capell    (remove "SpamMeNot" from reply-to eMail)

To receive email replies, put a replyable address in your Reply-To:
header. :-)

Hope this helps,
Greg
--
open(G,"|gzip -dc");$_=<<EOF;s/[0-9a-f]+/print G pack("h*",$&)/eg
f1b88000b620f22320303fa2d2e21584ccbcf29c84d2258084
d2ac158c84c4ece4d22d1000118a8d5491000000
EOF



Fri, 30 Jun 2000 03:00:00 GMT  
 alphabetical subset of hash keys

Quote:

>If I have a large hash, how can I run a routine on just the keys that
>start with a certain letter? I want something that looks like:

>    foreach $key (keysthatstartwithA %myhash) {
>        print "$myhash{$key}\n";
>    }

>to work like:

>    foreach $key (keys %myhash) {
>        if ( substr($key,0,1)=="A" ) { print "$myhash{$key}\n" };
>    }

>but without having to bang through every key in the hash to see if it
>starts with 'A' (that just seems inefficient to me)

>BTW - this hash is tied to a BTREE Berkely DB, so the hash keys will
>be returned in alphabetical order. What I'm trying to do is allow the
>user to 'query' the database by letter.

If you've got a BTREE Berkely DB, why not use the database facilities,
specifically the $db->seq method?

Mike Guy



Sat, 01 Jul 2000 03:00:00 GMT  
 alphabetical subset of hash keys

Am I missing something, or is there some reason why you can't
just seek to the first entry in the B-tree after, say, 'C',
and continue (using the each operator) until keys no longer
start with 'C'?  It is a B-tree, after all.  I don't have the
Berkeley DB man pages in front of me so I don't know what call
you use to seek prior to sequential access, but ....

        -joseph

Quote:

> If I have a large hash, how can I run a routine on just the keys that
> start with a certain letter? I want something that looks like:

>     foreach $key (keysthatstartwithA %myhash) {
>         print "$myhash{$key}\n";
>     }

> to work like:

>     foreach $key (keys %myhash) {
>         if ( substr($key,0,1)=="A" ) { print "$myhash{$key}\n" };
>     }

> but without having to bang through every key in the hash to see if it
> starts with 'A' (that just seems inefficient to me)

> BTW - this hash is tied to a BTREE Berkely DB, so the hash keys will
> be returned in alphabetical order. What I'm trying to do is allow the
> user to 'query' the database by letter.



Sat, 01 Jul 2000 03:00:00 GMT  
 
 [ 5 post ] 

 Relevant Pages 

1. split composite hash key into sub key fields.

2. hash keys order returned by keys() reproducible ?

3. exists() on sub-hash creates a key in super-hash

4. Sorting array of hash references by a hash key

5. complex foreach loop with deep hashes (sorted hash slices (using an array for keys))

6. Sort non-key in a Hash of Hash

7. Access a hash key by hash value ?

8. explain an hash assignment: $hash{'key'}++

9. dynamically creating a hash of hashes, reading keys/values from a file

10. exists() on sub-hash creates a key in super-hash

11. Sorting hash of hash by first then second key

12. getting keys of hashes of hashes

 

 
Powered by phpBB® Forum Software