Reputation: 11266
This is an over-engineered solution for something I think can be done better. Basically it takes an array of keys to create a filter string, which is checked against every key in the hash to see if that key has an index in the filter string... The exclude flag flips the logic to include or exclude based on the result of _filter. Probably not the best way. Any better ways?
sub _filter{
my ($filter,$key,$joiner) = @_;
$joiner = $joiner ? $joiner : '+';
my $i = index($filter,$key);
if($i >= 0){
my $c;
$c = substr($filter, $i-1, 1);
print STDERR "\nc => $c [$key][$i]";
if($i==0){ return 1; }
return($c eq $joiner);
}
return 0;
}
sub hashFilter{
my($hash,$filter_keys,$exclude) = @_;
return 0 unless isHash($hash) && $filter_keys;
$exclude = $exclude ? $exclude : 0;
my $filter = isArray($filter_keys)? join('+',@$filter_keys) : $filter_keys;
print STDERR "FILTER is > $filter";
my $p = {map { ( _filter($filter,$_) == $exclude ) ? ($_ => $$hash{$_}) : () } keys %$hash};
return $p;
}
#isArray() and isHash() just check the ref value for "ARRAY" or "HASH" respectively
...using standard perl without additional Modules! =]
Some thoughts here?
Using map, and index... are these fast-ish methods vs doing regex, or are there better functions to use?
Upvotes: 3
Views: 8017
Reputation: 37146
Hash slice, anyone? :
my %filtered_hash;
@filtered_keys = grep { exists $hash{$_} } @filtered_keys;
@filtered_hash{@filtered_keys} = @hash{@filtered_keys};
Upvotes: 9
Reputation: 57520
my %filtered_hash = map { $_ => $hash{$_} } grep { exists $hash{$_} } @filter_keys;
Upvotes: 16