Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Complicated Hash with array

by inblosam (Monk)
on Aug 08, 2006 at 04:47 UTC ( [id://566071]=perlquestion: print w/replies, xml ) Need Help??

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

I have some data that has the column titles (ItemName1...) for each of the objects (Apple, Orange, ....), and then multiple lines of objects that correspond to the column titles. What I am trying to do, but don't know where to go next, is to put all the data in a sort of hash array. The column titles would be the keys of the hash, but there would be a separate line for each line of data/objects. This is the code where I am at so far:
#!/usr/bin/perl -w use strict; use Data::Dumper; my $rawdata = qq| <COLUMNS>~ItemName1~ItemName2~ItemName3~ItemName4~ItemName5~</COLUMNS> <DATA>~Apple~Orange~Banana~Pear~Watermelon~</DATA> <DATA>~Blue~Red~Yellow~Brown~Purple~</DATA> <DATA>~Uno~Dos~Tres~Cuatro~Cinco~</DATA> |; my @datalines = split("\n",$rawdata); my @listings; my $header; foreach my $line (@datalines) { if ($line =~ /^<COLUMNS>(.+)<\/COLUMNS>/xg) { $header = $1; } elsif ($line =~ /^<DATA>(.+)<\/DATA>/xg) { push(@listings, $1); } } print Dumper(\$header); print Dumper(\@listings);


Michael
Thanks for your help!

Replies are listed 'Best First'.
Re: Complicated Hash with array
by GrandFather (Saint) on Aug 08, 2006 at 05:05 UTC

    Without any error checking this works for you sample:

    use warnings; use strict; my $rawdata = qq| <COLUMNS>~ItemName1~ItemName2~ItemName3~ItemName4~ItemName5~</COLUMNS> <DATA>~Apple~Orange~Banana~Pear~Watermelon~</DATA> <DATA>~Blue~Red~Yellow~Brown~Purple~</DATA> <DATA>~Uno~Dos~Tres~Cuatro~Cinco~</DATA> |; my @datalines = grep {length} split "\n",$rawdata; my @listings; my $header; foreach my $line (@datalines) { if ($line =~ /^<COLUMNS>(.+)<\/COLUMNS>/) { $header = $1; } elsif ($line =~ /^<DATA>(.+)<\/DATA>/) { push(@listings, $1); } } my %hoa; my @keys = grep {length} split '~', $header; for my $listing (@listings) { my @list = grep {length} split '~', $listing; push @{$hoa{$keys[$_]}}, $list[$_] for 0..$#keys; } print "$_ => @{$hoa{$_}}\n" for sort keys %hoa;

    Prints:

    ItemName1 => Apple Blue Uno ItemName2 => Orange Red Dos ItemName3 => Banana Yellow Tres ItemName4 => Pear Brown Cuatro ItemName5 => Watermelon Purple Cinco

    DWIM is Perl's answer to Gödel
      That works great. I will need to stare at that for a while to process it all though.

      Any suggestions on a way to parse through the data line by line (of the DATA rows) by calling it by the item name? Something like below, although this obviously doesn't work with the current hash, this is what I envisioned but am unsure of how to accomplish it:
      foreach my $data (@datalineshasharraything) { print "Item1 is ", $data{'ItemName1'}; print "Item2 is ", $data{'ItemName2'}; }
      Not sure if that is doable, as it is beyond my scope of Perl understanding. Any suggestions? Thanks


      Michael Jensen
        You can accomplish that inside the for (@listings) loop of GrandFather's solution by using a hash slice.
        for my $listing (@listings) { my @list = grep {length} split '~', $listing; my %data; @data{@keys} = @list; print "Item1 is ", $data{'ItemName1'}, $/; print "Item2 is ", $data{'ItemName2'}, $/; push @{$hoa{$keys[$_]}}, $list[$_] for 0..$#keys; }

        -- Hofmator

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (6)
As of 2024-03-28 16:23 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found