in reply to Re: Selecting a Specific Keys in Relation to a List
in thread Selecting a Specific Keys in Relation to a List
While your algorithm works (mostly), it trades a small memory gain for a lot of extra CPU work, especially as @do_not_want grows.
For every key in %hash, the code must loop through every member of @do_not_want. Grep does not short-circuit, so even after you've found 'ytd', you are still going to check 'mtd' and 'wtd'.
The other problem with this code is that if $hash{ytd_total} = 1000; is a desired report value, your grep will match and incorrectly exclude that value.
As long as pure textual equivalence is the matching criteria, using a hash for the lookup is going to be faster and make a tiny impact on memory.
If you need to do some kind of complex matching, then there is no way (that I know of) to avoid nested loops. But you can use a short circuited loop to avoid checking for any matches after the first. List::MoreUtils any comes to mind as an excellent way to handle this situation.
Here's a version that uses a hash
my %hash = ( ytd => 1.5, mtd => 2.0, wtd => 2.5, Jumbo_Tron => "United Center", Meat_Pie => "Gross", "Word" => "Association", ); my %do_not_want; @do_not_want{ qw(ytd mtd wtd) } = (); foreach my $k (keys %hash) { next if exists $do_not_want{$k}; print "$k => $hash{$k}\n"; }
Here's a version that matches hash keys against a regex:
use List::MoreUtils qw(any); my %hash = ( ytd => 1.5, mtd => 2.0, wtd => 2.5, Jumbo_Tron => "United Center", Meat_Pie => "Gross", "Word" => "Association", ); my @do_not_want = ( qr/ytd/, qr/mtd/, qr/wtd/ ); foreach my $k (keys %hash) { next if any { $k =~ $_ } @do_not_want ; print "$k => $hash{$k}\n"; }
Warning, all this code is untested. I modified it in a browser edit box.
TGI says moo
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^3: Selecting a Specific Keys in Relation to a List
by tuxz0r (Pilgrim) on Nov 02, 2007 at 03:38 UTC | |
by TGI (Parson) on Nov 02, 2007 at 18:33 UTC |