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

hi, i'm new to perl.....i have a file with a list of names and values....what is the best way to store that, in hashes or arrays so that i can go through the file and work with the individual names? i'm thinking arrays since i have duplicate names, but just wanted some suggestions from someone who's more familiar with perl. the file looks like:
amsterdam 23 amsterdam 88 london 65 ny 10 ny 16 la 21 la 65 miami 9 lapaz 10

Replies are listed 'Best First'.
Re: arrays or hashes
by insensate (Hermit) on Aug 27, 2002 at 14:58 UTC
    It largely depends on what you want to do with the data...are you trying to construct a summary of the digits based on the city keys? In that case I would create a hash of arrayrefs and then manipulate the data as you need:
    while(<DATA>){ ($city,$num)=split; push( @{$myhash{$city}}, $num ); }
    Now you have a hash with the city names as keys and each corresponding digit included in an arrayref of values. This node has some good insight into working with these data structures.
Re: arrays or hashes
by BrowserUk (Patriarch) on Aug 27, 2002 at 15:00 UTC

    How about a hash of arrays!

    eg. $hash{amsterdam} = [23, 88]; etc.

    You can generate that from your file using:

    #! perl -w use strict; my %data; # Choose a better name #open DATA, '<yourfile' or die "Couldn't open $DATA; $!"; while(<DATA>) { chomp; my ($place,$number) = split /\s+/; push @{$data{$place}}, $number; } #close DATA or warn "Couldn't close $DATA: $!"; for my $place (keys %data) { print $place, "\thas values: ("; print @{$data{$place}}[$_], ',' for (0 .. $#{$data{$place}}); print ")\n"; } __DATA__ amsterdam 23 amsterdam 88 london 65 ny 10 ny 16 la 21 la 65 miami 9 lapaz 10

    The program produces this output.

    C:\test>193169 miami has values: (9,) lapaz has values: (10,) ny has values: (10,16,) la has values: (21,65,) london has values: (65,) amsterdam has values: (23,88,) C:\test>

    I'll leave cleaning the output up to you:^)


    What's this about a "crooked mitre"? I'm good at woodwork!
Re: arrays or hashes
by talexb (Chancellor) on Aug 27, 2002 at 15:03 UTC
    You probably want to store them in a hash of arrays. Untested code:
    my %Data; while(<DATA>) { my ( $City, $Value ) = split; push ( @{$Data{ $City }}, $Value ); } __DATA__ amsterdam 23 amsterdam 88 london 65 ny 10 ny 16 la 21 la 65 miami 9 lapaz 10
    That should give you
    ( amsterdam => [23, 88], london => [65], ny => [10, 16], la => [21, 65], miami => [9], lapaz => [10] )

    --t. alex
    but my friends call me T.

Re: arrays or hashes
by the_slycer (Chaplain) on Aug 27, 2002 at 15:00 UTC
    If you are working with just the names - then yes, I would use an array, faster access.

    However, if you need the values associated with the names - your best be may be to build a hash of arrays.

    Alternately, if you just need to loop once, using both the names & values - forget an array or a hash, just split the data in the loop that you read the file :)
      i'm working with both names and values.....what is the best way to build a hash of arrays? thanks
        I would do something like this:

        my %data; while (<FILE>) { my ($name, $val) = split /\s+/; push @{ $data{$name} }, $val; }
        When you say working with both names and values, what are you trying to do with them? add all the second coulmn numbers for each name up? sort by something? what? depending on exactly what you are going to be doing with the data your options can be way different. for instance if you want to add all of the numbers up for each name you can do this:
        my %names; open (FILE, "data") or die "Cant open data: $!\n"; while (<DATA>) { chomp; my ($tempname, $tempnum) = split / /; $names{"$tempname"} += $tempnum; } close FILE;
        Or if you need to track all of the numbers seperatly you could use an HoA (Hash of ArrayRefs) such that you push (@{$names{"$tempname"}},$tempnum); values into it. let us know what you plan to do with the data and we can get you some decent data structs. =)

        -Waswas