Building Hash of Arrays from multiple files

Discussion in 'Perl Misc' started by joeri, Jul 17, 2003.

  1. joeri

    joeri Guest

    "Garry Short" <> wrote in message
    news:bf68hs$qjs$1$...
    > my %HoA;
    > my @filelist;
    > my $master_file = "master.list";
    >
    > open MASTER, $master_file or die "Can't open $master_file: $!\n";
    > my @master_list = <FILE>;
    > close FILE;
    > my $fc = 0; # file counter
    > foreach my $file (@master_list) {
    > open FILE, $file or die "Can't open $file: $!\n";
    > $fc++;
    > while (<FILE>) {
    > my ($key, $value) = split /=/;
    > if ($HoA{$key}) { # if this key already exists
    > push ($HoA{$key}, [ $value ]);
    > } else { # This is a new key
    > # I can do this ...
    > for (my $counter = 0; $counter < $fc; $counter++) {
    > push ($HoA{$key}, [ "" ]);
    > }
    > push ($HoA{$key}, [ $value ]);
    > # Would this work as I expect it to??
    > }
    > }
    > }
    > foreach $key (keys %HoA) {
    > my @list = $HoA{$key};
    > foreach my $elem (@list) {
    > print "$elem\t";
    > }
    > print "\n";
    > }


    you must "push" onto an array, so you have to make the value of your hash
    into an array. Try this instead:

    push(@{$HoA{$key}}, $value);

    You can still check the existence of the $key in the hash with

    if exists $HoA{$key}


    J
    joeri, Jul 17, 2003
    #1
    1. Advertising

  2. joeri

    Garry Short Guest

    Hi all,

    I'm having a little trouble coming up with a working solution for this hash
    of arrays.

    I've got a list of property files that I'm trying to display in a table
    (this is actually part of a CGI script, but that's not really relevant).

    These properties have a series of key=value pairs. However, each file may
    only have a selection of the pairs, and it's unlikely that any file will
    have all of the keys.

    This is easy enough when a key exists in every file, BUT ...

    1. How do I add a new key that hasn't existed in previous files, and add
    data to show that it doesn't exist in the previous files?

    2. How do I mark that the key from a previous file doesn't exist in this
    one?

    This is a rough sketch of what I've got so far:

    #!/usr/bin/perl -w

    my %HoA;
    my @filelist;
    my $master_file = "master.list";

    open MASTER, $master_file or die "Can't open $master_file: $!\n";
    my @master_list = <FILE>;
    close FILE;
    my $fc = 0; # file counter
    foreach my $file (@master_list) {
    open FILE, $file or die "Can't open $file: $!\n";
    $fc++;
    while (<FILE>) {
    my ($key, $value) = split /=/;
    if ($HoA{$key}) { # if this key already exists
    push ($HoA{$key}, [ $value ]);
    } else { # This is a new key
    # I can do this ...
    for (my $counter = 0; $counter < $fc; $counter++) {
    push ($HoA{$key}, [ "" ]);
    }
    push ($HoA{$key}, [ $value ]);
    # Would this work as I expect it to??
    }
    }
    }
    foreach $key (keys %HoA) {
    my @list = $HoA{$key};
    foreach my $elem (@list) {
    print "$elem\t";
    }
    print "\n";
    }

    I've not really done much with hashes before, and this is a fairly
    complicated one (for me, at least :)

    Is this likely to print the table as I expect it?
    Is there a better way of adding in new keys half way through (as suggested
    in the ELSE loop).
    Anyone got any ideas on how to indicate that the current file does NOT
    contain a key?

    TIA,

    Garry
    Garry Short, Jul 17, 2003
    #2
    1. Advertising

  3. Garry Short <> wrote in
    news:bf68hs$qjs$1$:

    > Hi all,
    >
    > I'm having a little trouble coming up with a working solution for this
    > hash of arrays.

    ....

    > These properties have a series of key=value pairs. However, each file
    > may only have a selection of the pairs, and it's unlikely that any
    > file will have all of the keys.


    Would Config::properties

    http://search.cpan.org/author/SALVA/Config-Properties-0.51/

    help?

    Sinan.

    --
    A. Sinan Unur

    Remove dashes for address
    Spam bait: mailto:
    A. Sinan Unur, Jul 17, 2003
    #3
  4. Garry Short <> wrote:

    > I'm having a little trouble coming up with a working solution for
    > this hash of arrays.
    >
    > I've got a list of property files that I'm trying to display in a
    > table (this is actually part of a CGI script, but that's not
    > really relevant).
    >
    > These properties have a series of key=value pairs. However, each
    > file may only have a selection of the pairs, and it's unlikely
    > that any file will have all of the keys.
    >
    > This is easy enough when a key exists in every file, BUT ...
    >
    > 1. How do I add a new key that hasn't existed in previous files,
    > and add data to show that it doesn't exist in the previous files?
    >
    > 2. How do I mark that the key from a previous file doesn't exist
    > in this one?


    I don't think a hash of arrays is the best way to approach this if
    your desired output is a table where the rows are keys and the
    columns are filenames. I'd use a hash of hashes, something like
    $HoH{$key}{$file} = $value, so you don't have to keep track of empty
    entries in an array. Once everything is stored in the hash of hashes
    you can print it any way you please.

    For example:

    use strict;
    use warnings;

    my %HoH;
    my $master_file = "master.list";

    open MASTER, $master_file or die "Can't open $master_file: $!\n";
    chomp(my @master_list = <MASTER>);
    close MASTER;
    foreach my $file (@master_list) {
    open FILE, $file or die "Can't open $file: $!\n";
    while (<FILE>) {
    chomp;
    my ($key, $value) = split /=/;
    $HoH{$key}{$file} = $value;
    }
    close FILE;
    }
    foreach my $key (sort keys %HoH) {
    print "$key: "; # maybe <tr> here in your CGI program? :)
    foreach my $file (@master_list) {
    print defined $HoH{$key}{$file} ?
    $HoH{$key}{$file} :
    'n/a';
    print "\t\t";
    }
    print "\n";
    }

    Hope this helps.
    David K. Wall, Jul 17, 2003
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    4
    Views:
    952
    M.E.Farmer
    Feb 13, 2005
  2. Philipp
    Replies:
    21
    Views:
    1,126
    Philipp
    Jan 20, 2009
  3. rp
    Replies:
    1
    Views:
    516
    red floyd
    Nov 10, 2011
  4. Adam Akhtar
    Replies:
    5
    Views:
    646
    Adam Akhtar
    Mar 25, 2008
  5. Älphä Blüë

    Hash of Hash of Arrays Question

    Älphä Blüë, Jul 18, 2009, in forum: Ruby
    Replies:
    5
    Views:
    667
    Älphä Blüë
    Jul 18, 2009
Loading...

Share This Page