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

Cannot use foreach on array of hashes

by MeinName (Novice)
on Dec 18, 2019 at 10:10 UTC ( [id://11110325]=perlquestion: print w/replies, xml ) Need Help??

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

Dear Perl monks,
I have the following array of hashes (at least my Dumper says so):

$VAR1 = [ { 'textfeldMini' => ' ', 'fragebogen_id' => '4388', 'aktivitaet_da +ta_id' => '48541093', 'zahlfeld' => '0.0', 'aktivitaetId' => '4854109 +1' }, { 'fragebogen_id' => '4389', 'aktivitaet_data_id' => '48541094', ' +zahlfeld' => '0.0', 'aktivitaetId' => '48541091' }, { 'fragebogen_id' => '4390', 'aktivitaet_data_id' => '48541095', ' +zahlfeld' => '0.0', 'aktivitaetId' => '48541091' }, { 'fragebogen_id' => '4391', 'textfeldStandard' => ' ', 'aktivitae +t_data_id' => '48541096', 'zahlfeld' => '0.0', 'aktivitaetId' => '485 +41091' }, { 'fragebogen_id' => '4392', 'textfeldStandard' => ' ', 'aktivitae +t_data_id' => '48541097', 'zahlfeld' => '0.0', 'aktivitaetId' => '485 +41091' }, { 'textfeldMini' => ' ', 'fragebogen_id' => '4393', 'aktivitaet_da +ta_id' => '48541098', 'zahlfeld' => '0.0', 'aktivitaetId' => '4854109 +1' }, { 'textfeldMini' => 'k.A.', 'fragebogen_id' => '4394', 'aktivitaet +_data_id' => '48541099', 'zahlfeld' => '0.0', 'aktivitaetId' => '4854 +1091' }, { 'fragebogen_id' => '4395', 'textfeldStandard' => ' ', 'aktivitae +t_data_id' => '48541100', 'zahlfeld' => '0.0', 'aktivitaetId' => '485 +41091' }, { 'fragebogen_id' => '4396', 'textfeldStandard' => ' ', 'aktivitae +t_data_id' => '48541101', 'zahlfeld' => '0.0', 'aktivitaetId' => '485 +41091' }, { 'fragebogen_id' => '4397', 'textfeldStandard' => ' ', 'aktivitae +t_data_id' => '48541102', 'zahlfeld' => '0.0', 'aktivitaetId' => '485 +41091' }, { 'textfeldMini' => 'k.A.', 'fragebogen_id' => '4398', 'aktivitaet +_data_id' => '48541103', 'zahlfeld' => '0.0', 'aktivitaetId' => '4854 +1091' }, { 'fragebogen_id' => '4399', 'textfeldStandard' => ' ', 'aktivitae +t_data_id' => '48541104', 'zahlfeld' => '0.0', 'aktivitaetId' => '485 +41091' }, { 'datumfeld' => '2000-01-01T00:00:00+01:00', 'fragebogen_id' => ' +4400', 'aktivitaet_data_id' => '48541105', 'zahlfeld' => '0.0', 'akti +vitaetId' => '48541091' }, { 'datumfeld' => '2000-01-01T01:00:00+01:00', 'fragebogen_id' => ' +4401', 'aktivitaet_data_id' => '48541106', 'zahlfeld' => '0.0', 'akti +vitaetId' => '48541091' }, { 'textfeldClob' => ' ', 'fragebogen_id' => '4402', 'aktivitaet_da +ta_id' => '48541107', 'zahlfeld' => '0.0', 'aktivitaetId' => '4854109 +1' }, { 'textfeldClob' => ' ', 'fragebogen_id' => '4403', 'aktivitaet_da +ta_id' => '48541108', 'zahlfeld' => '0.0', 'aktivitaetId' => '4854109 +1' } ];

and I would like to foreach-loop through it like so:

1136 foreach my $data (@aktData) 1137 { 1138 if ($data->{'fragebogen_id'} == $feedbackId) 1139 { 1140 #doStuff 1141 } 1142 }

but I get an error "Not a HASH reference at ... line 1138".
I did a Dumper print on @aktData as well as $data and both times I get this hash array as output, which means the error message is accurate, but I have no clue, why $data is not one element of my array, but the whole array itself.

Can somebody please help me with this?

Replies are listed 'Best First'.
Re: Cannot use foreach on array of hashes
by hippo (Bishop) on Dec 18, 2019 at 10:17 UTC
    I did a Dumper print on @aktData as well as $data and both times I get this hash array as output

    The likely explanation is that @aktData is not an array of hashes but rather an array with one element which is itself an arrayref of hashes. eg.

    #!/usr/bin/env perl use strict; use warnings; use Data::Dumper; my @aktData = ([ { foo => 'bar' }, { foo => 'baz' } ]); print 'Array: ' . Dumper (@aktData); foreach my $data (@aktData) { print 'Element: ' . Dumper ($data); }

    Produces this:

    Array: $VAR1 = [ { 'foo' => 'bar' }, { 'foo' => 'baz' } ]; Element: $VAR1 = [ { 'foo' => 'bar' }, { 'foo' => 'baz' } ];

      Hi hippo,
      it seems to be kind of like that. I suspect that to be the case, because of how I initialized the array, but I'm puzzled as to why it occurs right now. It worked just last week.

      The way this array comes to be is as follows:
      I have a large hash with lots of information on an activity. It has an ID, multiple status values, an associated object, possibly multiple associated contacts and multiple instances of so-called activityData, which is the concrete content of the activity.

      The content looks like this:

      $VAR1 = { 'activityContacts' => [ { 'foo' => 'bar', 'baz' => 'foo', ... }, { 'foo' => 'bar', 'baz' => 'foo', ... } ], 'currentAgent' => { 'foo' => 'bar', 'baz' => 'foo', ... }, 'activityData' => [ { 'textfeldMini' => ' ', 'fragebogen_id' => '4388', 'aktivitae +t_data_id' => '48541093', 'zahlfeld' => '0.0', 'aktivitaetId' => '485 +41091' }, { 'fragebogen_id' => '4389', 'aktivitaet_data_id' => '48541094 +', 'zahlfeld' => '0.0', 'aktivitaetId' => '48541091' }, { 'fragebogen_id' => '4390', 'aktivitaet_data_id' => '48541095 +', 'zahlfeld' => '0.0', 'aktivitaetId' => '48541091' }, { 'fragebogen_id' => '4391', 'textfeldStandard' => ' ', 'aktiv +itaet_data_id' => '48541096', 'zahlfeld' => '0.0', 'aktivitaetId' => +'48541091' }, { 'fragebogen_id' => '4392', 'textfeldStandard' => ' ', 'aktiv +itaet_data_id' => '48541097', 'zahlfeld' => '0.0', 'aktivitaetId' => +'48541091' }, { 'textfeldMini' => ' ', 'fragebogen_id' => '4393', 'aktivitae +t_data_id' => '48541098', 'zahlfeld' => '0.0', 'aktivitaetId' => '485 +41091' }, { 'textfeldMini' => 'k.A.', 'fragebogen_id' => '4394', 'aktivi +taet_data_id' => '48541099', 'zahlfeld' => '0.0', 'aktivitaetId' => ' +48541091' }, { 'fragebogen_id' => '4395', 'textfeldStandard' => ' ', 'aktiv +itaet_data_id' => '48541100', 'zahlfeld' => '0.0', 'aktivitaetId' => +'48541091' }, { 'fragebogen_id' => '4396', 'textfeldStandard' => ' ', 'aktiv +itaet_data_id' => '48541101', 'zahlfeld' => '0.0', 'aktivitaetId' => +'48541091' }, { 'fragebogen_id' => '4397', 'textfeldStandard' => ' ', 'aktiv +itaet_data_id' => '48541102', 'zahlfeld' => '0.0', 'aktivitaetId' => +'48541091' }, { 'textfeldMini' => 'k.A.', 'fragebogen_id' => '4398', 'aktivi +taet_data_id' => '48541103', 'zahlfeld' => '0.0', 'aktivitaetId' => ' +48541091' }, { 'fragebogen_id' => '4399', 'textfeldStandard' => ' ', 'aktiv +itaet_data_id' => '48541104', 'zahlfeld' => '0.0', 'aktivitaetId' => +'48541091' }, { 'datumfeld' => '2000-01-01T00:00:00+01:00', 'fragebogen_id' +=> '4400', 'aktivitaet_data_id' => '48541105', 'zahlfeld' => '0.0', ' +aktivitaetId' => '48541091' }, { 'datumfeld' => '2000-01-01T01:00:00+01:00', 'fragebogen_id' +=> '4401', 'aktivitaet_data_id' => '48541106', 'zahlfeld' => '0.0', ' +aktivitaetId' => '48541091' }, { 'textfeldClob' => ' ', 'fragebogen_id' => '4402', 'aktivitae +t_data_id' => '48541107', 'zahlfeld' => '0.0', 'aktivitaetId' => '485 +41091' }, { 'textfeldClob' => ' ', 'fragebogen_id' => '4403', 'aktivitae +t_data_id' => '48541108', 'zahlfeld' => '0.0', 'aktivitaetId' => '485 +41091' } ], 'activity' => { 'foo' => 'bar', 'baz' => 'foo', ... } };

      Then I'm breaking that hash up like this:

      my $aktAkt = $aktivitaet->{'activity'}; my @aktData = $aktivitaet->{'activityData'}; my $aktAgent = $aktivitaet->{'currentAgent'};

      But that obviously doesn't work.
      With your help I could figure it out why, now: Looking at the entire hash, the part of it that I want is encapsulated in a list, which can't be interated in the same way as an array can (square brackets instead of wavy ones). Changing my code to the following helped:

      my $aktData = $aktivitaet->{'activityData'}; #Note the scalar variable ... foreach my $data (@$aktData) { if ($data->{'fragebogen_id'} == $feedbackId) { #doStuff } }

      Thanks for your help!

      Now, I just have to figure out where that weird list comes from. I certainly didn't put it there...

        Square brackets [...] in a data structure like that is a reference to an array. A list (...) within a data structure like that is pretty meaningless as lists get flattened.

        Either of the following two are the correct way of iterating through it:

        my $aktData = $aktivitaet->{'activityData'}; foreach my $data (@$aktData) { ... }
        my @aktData = @{ $aktivitaet->{'activityData'} }; foreach my $data (@aktData) { ... }

        Edit: here's an example of why a list (...) within a hashref isn't what you want.

        use Data::Dumper; my $data = { "list" => ( "foo", "bar", "baz" ), }; print Dumper($data);
Re: Cannot use foreach on array of hashes
by BillKSmith (Monsignor) on Dec 18, 2019 at 15:05 UTC
    Data::Dumper expects either a scalar or reference variable (Refer: DESCRIPTION section of Data::Dumper). You should pass it a reference to you structure. Remember to interpret $VAR1 as a reference to your structure. Using hippo's example:
    #!/usr/bin/env perl use strict; use warnings; use Data::Dumper; my @aktData = ([ { foo => 'bar' }, { foo => 'baz' } ]); #print 'Array: ' . Dumper (@aktData); print 'Array: ' . Dumper (\@aktData); foreach my $data (@aktData) { print 'Element: ' . Dumper ($data); } OUTPUT: Array: $VAR1 = [ [ { 'foo' => 'bar' }, { 'foo' => 'baz' } ] ]; Element: $VAR1 = [ { 'foo' => 'bar' }, { 'foo' => 'baz' } ];

    The Dumper output clearly shows the problem he describes.

    Bill

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (3)
As of 2024-04-18 22:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found