Reputation: 1471
I'm dealing with hashes like:
my %hash1 = (
key1 => 0,
key2 => 1,
key3 => 0,
);
I want to do something if the value of all values (not just one value) of %hash1
is 1.
How to write that?
For reference, I can write:
for $key ( keys %hash1 ) {
if ( $hash1{$key} == 1 ){
#do something
}
}
which is wrong because even if one key has a value equal to 1, the #do something
part of the code will run. The code I wrote apparently does something if at least one key equals 1. It would be nice to have something like:
for $key ( keys %hash1 ) {
if ( exists( $hash1{$key} == 1 ) ){
#do something
}
}
Upvotes: 1
Views: 1966
Reputation: 57646
You can use List::MoreUtils
:
use List::MoreUtils qw/all/;
if (all { $_ == 1 } values %hash) {
# iterate the hash
while (my ($k, $v) = each %hash) {
...
}
}
The all { something($_) } @list
is a fancy way of writing
!grep { !something($_) } @list
which uses De Morgan's Law.
Note that my %hash = { key => 1 }
does not create the data structure you wanted. Rather, this maps a key "HASH(0x1234567)"
to undef
. If you use warnings
, you'll get a message telling you that you are using a (hash) reference where a list was expected. Initialize hashes with a key-value list: my %hash = ( key => 1)
.
Upvotes: 4
Reputation: 31972
Set a flag within the if
and check its value after the loop.
$all_are_one = $all_are_one && $hash1{$key} == 1
You would need to set it to true before the loop
Upvotes: 2