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

map to hash of arrays

by emilford (Friar)
on Jul 22, 2004 at 20:45 UTC ( [id://376713]=perlquestion: print w/replies, xml ) Need Help??

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.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (8)
As of 2024-04-18 16:18 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found