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

I have data returned from a sql query that comes as:
Row 1 label1 : item1 label2 : item1 Row 2 label1 : item2 label2 : item2
I need all of the information after the colons. The odd numbered values (label1) I want to use as a hash key and the even numbered values (label2) I want to use as the hash value. I've gotten that far with the following: my %hash = map { m!(?:\S+) : (\S+)! } @stuff_from_query;. The problem I've encountered is that the data after label1 could be duplicate, but with different values for label2. The current code stores only one value, overwritting the previous. I need to somehow incorporate a push so that the value of the hash is an anonymous array, containing all found label2 values.

Is there a nifty way I can still incorporate this into a map line?

Replies are listed 'Best First'.
Re: map to hash of arrays
by ccn (Vicar) on Jul 22, 2004 at 21:03 UTC

    Is it what you want?

    use Data::Dumper; my $data = <<EOT; Row 1 label1 : item1 label2 : item1 Row 2 label1 : item2 label2 : item2 EOT push @{$hash{$1}}, $2 while $data =~ /(\S+)\s*:\s*(\S+)/g; print Dumper(\%hash);

    $VAR1 = { 'label1' => [ 'item1', 'item2' ], 'label2' => [ 'item1', 'item2' ] };
      Not exactly. Let me try my explanation again. Here is a chunk of sample data to illustrate what I'd like to do.
      Row 17 object_label : yang object_id : 123456 Row 18 object_label : yang object_id : 789101112 Row 19 object_label : yang object_id : 13141516171819
      The data comes in exactly like that, line by line. I need to ignore the Row \d+ lines and grab the rest of the information, so that I end up with a hash of arrays where 'object_label' are used as keys and 'object_id' with the same 'object_label' are items in an array.
      %hash = { 'yang' => [ '123456', '789101112', '13141516171819' ] }

        please try this: push @{$hash{$1}}, $2 while $data =~ /object_label\s+:\s+(\S+)[^:]+:\s+(\S+)/g;

Re: map to hash of arrays
by rnahi (Curate) on Jul 22, 2004 at 21:26 UTC

    Perhaps DBI Recipes has something useful for you.

    Check the sections about lists of hashes and hashes of hashes.

Re: map to hash of arrays
by dpuu (Chaplain) on Jul 22, 2004 at 21:13 UTC
    It is obviously possible, but it would not be "nifty". In fact, I think it'd be worse solution than just using a C<for> loop in the first place. You just have to build a temportary hash off to the side. But if you're going to build a tmp hash, then you might as well just build the real one.

    --Dave
    Opinions my own; statements of fact may be in error.

      That's my issue. I want to build the real hash of arrays without the need of a temporary one. I'm just not sure how to go about doing that.
        Use a while loop, not a map:
        my %hash; my $key; while (<>) { /\S+ : (\S+)/ or die "unexpected line format: $_"; my $value = $1; if (defined $key) { push @{ $hash{$key} }, $value; undef $key; else { $key = $value; } }
        --Dave
        Opinions my own; statements of fact may be in error.