Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

hashes of arrays

by mbond (Beadle)
on Apr 03, 2001 at 23:16 UTC ( [id://69428]=perlquestion: print w/replies, xml ) Need Help??

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

okay ... Question: I want to store an array (the contents of a file) in a hash.

please excuse lack of error checking and such, i'm just not in the mood today.

foreach (@file) { open(FILE,"$_"); $hash{$_}{file_contents} = <FILE>; close(FILE) }

As i expected it to do, if i print out $hash{$_}{file_contents} it prints only the first line of the file.... is there a way to get it to contain the whole array?

Mbond.

Replies are listed 'Best First'.
Re: hashes of arrays
by suaveant (Parson) on Apr 03, 2001 at 23:19 UTC
    { local $/; foreach (@file) { open(FILE,"$_"); $hash{$_}{file_contents} = <FILE>; close(FILE) } }
    that sets line separator to undef, and slurps in whole file instead of one line.
                    - Ant
      Another solution, since you said you wanted an array, is to read the file in array context, without changing the input line separator :
      @{$hash{$_}{file_contents}} = <FILE>;
      -- the array guy
      Two tiny nitbits:
      1. It's a good thing to put the local in a block (so ++), but with unexperienced users (the poster) it may be nice to note what it does. Well, the {local....} BLOCK restricts the scope of local to that block. So after the block, the $/ has it's original value (the line separator). One can read more about these and other vars in perlvar.
      2. (Really tiny)The foreach was copied from the original post (and it works), but here is a for more precise. A foreach loop is used to change the contents of an array, for is not. So for reading in a file, I would recommend for. A typical use for foreach:
        @array = 0..100; foreach $item (@array){ $item += 10 if $item <100; } print join "\n", @array; #prints the numbers 10 to 109 and 100
        You can read more about it in for vs foreach.
      Hope this helps,

      Jeroen
      "We are not alone"(FZ)
      Update: For clarity, for and foreach *are* synonyms. It's just a matter of convention....

        I tried the following:
        #!/usr/local/bin/perl use strict; my @array = ('one', 'two', 'three'); for my $element (@array) { $element = uc($element); } for my $element (@array) { print "$element\n"; } exit;
        The output was:
        ONE
        TWO
        THREE

        In this regard the for does in fact seem to be synonymous with foreach. In the extent that the elements of the array are changed both function the same.

        But I must admit that by programming habit and for the sake of readiblity I adhere to the convention:

        foreach loop to change the contents of an array
        "for" when I'm not.

        In spite of my habits and preferences apparently they both work the same. But alas my C background has me using for when I'm just stepping through array indexes.

      woo.

      Thanks... I'd like it emphasize that making it local to a block is a good thing ... for some reason i didn't bother when i tested it real quick ... ;-)

      feel free to beat me for my stupidity.

      Mbond.
Re: hashes of arrays
by ton (Friar) on Apr 03, 2001 at 23:39 UTC
    try this:
    foreach (@file) { open(FILE,"$_"); @{$hash{$_}{file_contents}} = <FILE>; close(FILE) }
    note that $hash{$_}{file_contents} contains a _reference_ to an array, not an array.
Re: hashes of arrays
by chipmunk (Parson) on Apr 04, 2001 at 06:34 UTC
    Here's an alternate syntax to store an array ref: $hash{$_}{file_contents} = [ <FILE> ]; The result will be the same as the @{} form suggested above (except if $hash{$_}{file_contents} already has some non-array-ref value in it; the @{} form won't do the right thing in that case).
Re: hashes of arrays
by SuperCruncher (Pilgrim) on Apr 04, 2001 at 02:51 UTC
    This isn't really answering your question, but I feel it is important to point out something that you're doing.
    open(FILE,"$_");
    When you do "$foo", it incurs a slight performance hit. Simply $foo on its own is better. Also, apparently, if $foo happens to be a scalar reference, Perl will dereference it if you don't put it in quotes, but won't otherwise. I doubt you want to open a file named with the memory address of the reference?

    See the part of the Perl FAQ that says "What's wrong with always quoting "$vars"?"

      The performance hit for stringfying $foo pales in comparison to the overhead of the open().

      Don't worry about performance at this level. It's like trying to pry small stones out of your tires so that your car will go faster. It just isn't worth it. Worry about effective use of your time, and your reader's time, instead.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://69428]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (5)
As of 2024-03-29 13:58 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found