in reply to The Art of Hashing

... but not sure how to make (hash?) to just type smith and get both emails.

Two points here: 1) partial match and 2) multiple values to one key

1. For perl hashes, the only way to get matching keys of a hash for a given string, is performing a pattern match on the entire set of keys.

my @matching_keys = grep /$customer/, keys %Customer;

There are other hash implementations close to the perl core which live in extensions. For instance, there is DB_File which interfaces to Berkeley DB and provides binary trees. This implementation has partial match built in.

2. A perl hash consists of key/value pairs. If you want to store more than one item in the value slot, you have to store the reference to a container - a reference to an anonymous array or hash, which you later dereference.

# $Customer{$customer} = $_; push @{$Customer{$customer}}, $_; # use value slot as anonymous ar +ray # later # print "Customer: $Customer{$customer}\n"; print join("\n", "Customer:", @{$Customer{$customer}}), "\n" +;

Again, the DB_File module is an alternative here. Its BTREE file type optionally allows a single key to be associated with an arbitrary number of values. File isn't necessarily a external file, since Berkeley DB allows the creation of in-memory databases.

See grep, push, join and DB_File.

perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'

Replies are listed 'Best First'.
Re^2: The Art of Hashing
by BrowserUk (Patriarch) on Jun 16, 2014 at 09:24 UTC
    1. For perl hashes, the only way to get matching keys of a hash for a given string, is performing a pattern match on the entire set of keys.
    my @matching_keys = grep /$customer/, keys %Customer;

    As some guy who used to be famous around here once said: "that's like buying and Uzi and using it to club your enemy to death".

    It's also very misleading because the hash is serving no useful purpose in that construct.

    It would be considerably cheaper to put the list of keys into an array and grep that than force Perl to re-walk the hash structure to generate the list of strings for grep each time around.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      Of course I can't but fully agree with you and thank you for the critic.
      Yes, storing the keys in an array is much cheaper - and partial match isn't what perl hashes are made for; that's better done with BTREE structures.

      perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
      that's like buying and Uzi and using it to club your enemy to death
      Indeed, an UZI is a very bad choice for a club. I'd suggest an AK47 or an M16. A Lee Enfield or a Mauser 98K, is an even better choice.

      CountZero

      A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

      My blog: Imperial Deltronics