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 (Archbishop) 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