Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Accessing this array ref.

by Anonymous Monk
on Apr 03, 2013 at 18:17 UTC ( #1026887=perlquestion: print w/replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks!
I have an array like this:
$VAR1 = [ { 'name' => 'Discount', 'reference' => '100 ', 'type' => 'Paper' }, { 'name' => 'Documents', 'reference' => '100 ', 'type' => 'Paper' }, { 'name' => 'Money', 'reference' => '340 ', 'type' => 'Plastic' }, { 'name' => 'State', 'reference' => '40 ', 'type' => 'Cotton' }, { 'name' => 'Slice', 'reference' => '30 ', 'type' => 'Cotton' }, { 'name' => 'Part', 'reference' => '45 ', 'type' => 'Cotton' }, ]
I would like to access the data in this array and have the results as:
for ( @{ $my_array } ) { print "$_\n"; } print "Results: Paper: Discount - 100 Documents - 100 Plastic: Money - 340 Cotton: State - 40 Slice - 30 Part - 45

Kind of lost on how to get this going, any help?
Thanks for the help!

Replies are listed 'Best First'.
Re: Accessing this array ref.
by SuicideJunkie (Vicar) on Apr 03, 2013 at 18:41 UTC

    You have an array reference. Each element of the array is a hash reference.

    So, when you loop, you are doing:

    for my $hashRef ( @$my_array_ref ) # Curlies aren't needed here since +$my_array_ref is a simple variable name { ... }

    For each hash ref, you can inspect the contents via: $hashRef->{name} or $hashRef->{type} etc...

    It looks like you want to spin through all the data and build a new Hash of Hashes (HoH):

    $results->{$transactionType}{$purchasedThing} += $amountSpent
    or some such like that.

    When looping through the hashes to display, you probably want to sort the keys so that you print in the same order each time.

    for my $transactionType (sort keys %$results) { for my $purchasedThings (sort keys %{ $results->{$transactionType} } +) # Curlies here to mark out what to dereference { printf("spent \$%5d on %20s using %20s\n", $results->{$transactionType}{$purchasedThings}, $purchasedThings, $transactionType, ); } }
      your explanation makes sense, still having problems, I can print the first item from the array like this:
      print $results->[0];
      But running your code is giving me": Not a HASH reference".

        It sounds like you're defining $results somewhere that you haven't shown, and making it an array ref.

        As I understand it, you want results to be a hash of hashes, so just declare it as my $results; or my $results = {};

Re: Accessing this array ref.
by Loops (Curate) on Apr 03, 2013 at 18:58 UTC

    You want to loop through the array, printing each item. Since the array is already sorted into groups, you just print a new group header when the value changes:

    use feature 'say'; my $type; for my $entry (@$VAR1) { if ( $entry->{type} ne $type ) { $type = $entry->{type}; say $type; } say "\t$entry->{name} - $entry->{reference}"; }
      This would do it, I could combined all the data into one variable and print at once instead of printing them in the IF, right?
        I don't understand your question. If the data is sorted as Loops said, his solution should work for you.
Re: Accessing this array ref.
by hdb (Monsignor) on Apr 03, 2013 at 21:30 UTC
    use strict; use warnings; my $VAR1 = [ { 'name' => 'Discount', 'reference' => '100 ', 'type' => 'Paper' }, { 'name' => 'Documents', 'reference' => '100 ', 'type' => 'Paper' }, { 'name' => 'Money', 'reference' => '340 ', 'type' => 'Plastic' }, { 'name' => 'State', 'reference' => '40 ', 'type' => 'Cotton' }, { 'name' => 'Slice', 'reference' => '30 ', 'type' => 'Cotton' }, { 'name' => 'Part', 'reference' => '45 ', 'type' => 'Cotton' }, ]; my %results; $results{$_->{type}}{$_->{name}} += $_->{reference} for (@{$VAR1}); print "Results:\n"; for my $type (keys %results) { print "\t$type:\n"; for my $name (keys %{$results{$type}} ) { print "\t\t$name - ".$results{$type}{$name}."\n"; } }
Re: Accessing this array ref.
by arnaud99 (Beadle) on Apr 04, 2013 at 07:37 UTC

    Hi

    This is a possible other way to come up with the same output.

    use Modern::Perl; my $data = [ { 'name' => 'Discount', 'reference' => '100 ', 'type' => 'Paper' }, { 'name' => 'Documents', 'reference' => '100 ', 'type' => 'Paper' }, { 'name' => 'Money', 'reference' => '340 ', 'type' => 'Plastic' }, { 'name' => 'State', 'reference' => '40 ', 'type' => 'Cotton' }, { 'name' => 'Slice', 'reference' => '30 ', 'type' => 'Cotton' }, { 'name' => 'Part', 'reference' => '45 ', 'type' => 'Cotton' }, ]; #recreate a data structure from the existing one, #but this time the main key is the type. my %result; foreach my $elem(@$data) { my $type = $elem->{type}; #create an array ref for that type if (! exists $result{$type} ) { $result{$type} = []; } #store name an reference under that type push @{ $result{$type} }, { name => $elem->{name}, reference => $elem->{reference}, }; } #loop through the new struct, and for each type, #print the list of names and references foreach my $a_type (sort {$a cmp $b} keys %result) { say $a_type; foreach my $a_ref( @{ $result{$a_type} } ) { say "\t", $a_ref->{name}, ': ', $a_ref->{reference}; } }

    Output

    Cotton State: 40 Slice: 30 Part: 45 Paper Discount: 100 Documents: 100 Plastic Money: 340

    Cheers.

    Arnaud

Re: Accessing this array ref.
by TJPride (Pilgrim) on Apr 04, 2013 at 12:34 UTC
    If the original order isn't important, here's one alphabetically sorted:
    use strict; use warnings; my $array = [ { 'name' => 'Discount', 'reference' => '100 ', 'type' => 'Paper' }, { 'name' => 'Documents', 'reference' => '100 ', 'type' => 'Paper' }, { 'name' => 'Money', 'reference' => '340 ', 'type' => 'Plastic' }, { 'name' => 'State', 'reference' => '40 ', 'type' => 'Cotton' }, { 'name' => 'Slice', 'reference' => '30 ', 'type' => 'Cotton' }, { 'name' => 'Part', 'reference' => '45 ', 'type' => 'Cotton' }, ]; my %hash; $hash{$_->{'type'}}{$_->{'name'}} = $_->{'reference'} for @$array; print "Results:\n"; for my $k1 (sort keys %hash) { print " $k1:\n"; for my $k2 (sort keys %{$hash{$k1}}) { print " $k2 - $hash{$k1}{$k2}\n"; } }
    Output:
    Results: Cotton: Part - 45 Slice - 30 State - 40 Paper: Discount - 100 Documents - 100 Plastic: Money - 340

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1026887]
Approved by Corion
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (5)
As of 2017-12-17 12:39 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    What programming language do you hate the most?




















    Results (464 votes). Check out past polls.

    Notices?