foreach $id (keys %hashes) { push @ids, $id if ( cond($hashes{$id}) ); } sub cond { my %line = %{shift}; return ( ( ($line{'key1'} eq "foo") and ($line{'key1'} eq "bar") ) or ($hashes{$id}{'key4'} < 10) ); }