3

Are there Perl functions that work like Python functions all or any? This answer from Jobin is a short explanation of how both functions are working.

I want to determine (without loop) if all error-msg's are defined and ne "" in the following structure:

$VAR1 = [{
  'row' => [{
      err_msg => "msg1",
      a => "a1",
      b => "b1"
    },
    {
      err_msg => "msg2",
      a => "a2",
      b => "b2"
    }]
},
{
  'row' => [{
      err_msg => "msg3",
      a => "a3",
      b => "b3"
    },
    {
      err_msg => "msg4",
      a => "a4",
      b => "b4"
    }]
}]
Chris
  • 310
  • 4
  • 14

1 Answers1

8

It's impossible to perform the check without looping, but you could indeed use all to do this.

use List::Util qw( all );

my $ok =
   all {
      all { $_->{err_msg} }
         @{ $_->{row} }
   }
      @$VAR1;

or

use List::Util qw( all );

my $ok =
   all { $_->{err_msg} }
      map { @{ $_->{row} } }
         @$VAR1;

The first version is more efficient because it only looks at a group if all the previous groups check out ok, whereas the second version unconditionally does work for every group. This difference is unlikely to matter, though.

ikegami
  • 367,544
  • 15
  • 269
  • 518
  • `all { $_->{err_msg} }` also considers `0` an invalid value. Adjust as necessary. – ikegami Sep 20 '18 at 20:03
  • first version unfortunately always returns `true`, even for non-existing keys. But second version works great :) – Chris Sep 20 '18 at 21:35
  • 1
    `all { length $_->{err_msg} }` will be true for 0 but not an empty string or undef. But note it will warn on undef before Perl 5.12. – Grinnz Sep 20 '18 at 23:46
  • @Chris For what input do you see that? (What do you mean by "_non-existing keys_"?) It works in my tests. – zdim Sep 21 '18 at 00:53
  • 1
    @Chris. The first version works fine. For example, if I comment out the first `err_msg` line in your data structure, it returns false. – ikegami Sep 21 '18 at 04:14