http://www.perlmonks.org?node_id=451145

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

How to build a hash? This is the way if you know all your elements.
%hash = ( key1 => 'value1', key2 => 'value2', key3 => 'value3', );
But how can I build a hash if I dont know how much data or what kind of data will be read out of a file for example.   How to "push" unknown quatities of data into a hash?   Thank you very much.

janitored by ybiC: Minor format cleanup, including balanced <code> tags around snippet

Replies are listed 'Best First'.
Re: How to build a hash?
by Roy Johnson (Monsignor) on Apr 25, 2005 at 12:10 UTC
    Usually by assigning one element at a time: $hash{$key} = $value; where $key and $value are determined (often within a loop) at runtime.

    Caution: Contents may have been coded under pressure.
      the best source i've found about hashes is howto-hash. Bookmark it, and you'll always know much about them.
Re: How to build a hash?
by salva (Canon) on Apr 25, 2005 at 12:13 UTC
    you can create an empty hash, and insert key-value pairs on it later, i.e. as you read them from STDIN:
    my %hash; while(<>) { chomp; my ($key, $value) = split('=', $_); $hash{$key} = $value; }
Re: How to build a hash?
by prasadbabu (Prior) on Apr 25, 2005 at 12:14 UTC

    You refer perldata, this may help you.

    As Roy Johnson suggested,the usual way is

    $hash{$key}=$value;

    Prasad

Re: How to build a hash?
by bart (Canon) on Apr 25, 2005 at 13:34 UTC
    Perl is a dynamic language, there's no need at all to know beforehand how many items there will be in a hash or array, or how long a string will be.

    Just add one item for every new one that you need, whenever you like.

    And no, the item will not be pushed at the end. Hashes are intrinsically unordered, you generally have no idea where it'll end up in the hash.

Re: How to build a hash?
by eibwen (Friar) on Apr 25, 2005 at 15:50 UTC

    I've found the Programming Language Examples alike Cookbook to be a particularly handy reference. For example, an excerpt on creating a hash:

    #----------------------------- %age = ( "Nat", 24, "Jules", 25, "Josh", 17 ); #----------------------------- $age{"Nat"} = 24; $age{"Jules"} = 25; $age{"Josh"} = 17; #----------------------------- %food_color = ( "Apple" => "red", "Banana" => "yellow", "Lemon" => "yellow", "Carrot" => "orange" ); #----------------------------- %food_color = ( Apple => "red", Banana => "yellow", Lemon => "yellow", Carrot => "orange" ); #-----------------------------

Re: How to build a hash?
by mda2 (Hermit) on Apr 27, 2005 at 00:51 UTC
Re: How to build a hash?
by Anonymous Monk on Apr 25, 2005 at 12:18 UTC
    Thank you, but would that not just rewrite the hash so only one element at a time will be existent in the hash? So you sure that elements will be just "append" to the hash if keys are not already existing?

      Trust us. We're sure it'll work :)

      If you don't believe us then why not write a little test program.

      my %hash; $hash{one} = 1; $hash{two} = 2; $hash{three} = 3; foreach (keys %hash) { print "$_ -> $hash{$_}\n"; }
      --
      <http://www.dave.org.uk>

      "The first rule of Perl club is you do not talk about Perl club."
      -- Chip Salzenberg

      No, like an array element ($array[$n]) the accessor of a hash element ($hash{'foo'}) is also an lvalue (basically you can assign a value to it). This method of accessing or modifying one value at a time doesn't affect the rest of the hash.

      You can also modify several elements at once using a hash slice, for example
      @hash{'foo','bar','baz'} = (1,2,3);
      Only when you say %hash are you definitely effecting the entire hash.
      %hash = ('foo',1,'bar',2'baz',3); # whole hash overwritten $hash{foo} = 1; # only one element created or modified @hash{@array} = (1,2,3); # only elements specified in @array overwritt +en, or created.
      I had myself problems with it recently. As long as you storing scalars, it work perfectly as coded in the examples above. When it comes to references, your fears become true.
      There is no such thing as a malloc in C or a new in C++(Ok, there is a new, but somehow different). What you have to do is placing brackets around an array or curly braces around a hash to get a copy in memory, that is not overwritten.
      For example: to create a hash of references to hashes:
      my %my_hash; sub my_store($\%){ my($key,$ref) = @_; $my_hash{$key} = {%$ref} }
      (example not tested)
        I had myself problems with it recently. As long as you storing scalars, it work perfectly as coded in the examples above. When it comes to references, your fears become true.

        You sound a little confused. You can only ever store scalars in a hash. A reference is just a special kind of scalar. You can never overwrite an entire hash by assigning to one of its values.

        my %my_hash; sub my_store($\%){ my($key,$ref) = @_; $my_hash{$key} = {%$ref} }

        I'd guess it's almost certainly the unnecessary use of prototypes that is confusing you there :)

        --
        <http://www.dave.org.uk>

        "The first rule of Perl club is you do not talk about Perl club."
        -- Chip Salzenberg