map for hashes in Perl
开发者_C百科Is there a hash equivalent for map
?
my %new_hash = hash_map { new_key($a) => new_val($b) } %hash;
I know that I could loop through the keys.
List::Pairwise claims to implement exactly that syntax -- see mapp
, grepp
. I haven't used it though.
Also, you can do it as
%new_hash = map { new_key($_) => new_value($hash{$_}) } keys %hash;
which I admit looks clumsier if %hash
is really a $deeply->{buried}->{hash}
. I prefer using $temp = ...; map {...} keys %$temp
in such cases.
I really can’t see what you are trying to do here. What does “a hash equivalent for map
” even mean? You can use map
on a hash just fine. If you want the keys, just use keys
; for example"
@msglist = map { "value of $_ is $hash{$_}" } keys %hash
although usually
say "value of $_ is $hash{$_}" keys %hash;
is just fine.
If you want both, then use the whole hash.
For assignment, what’s wrong with %new_hash = %old_hash
?
Do you have deep-copy issues? Then use Storable::dclone
.
Do you want both key and value available in the closure at the same time? Then make a bunch of pairs with the first map:
@pairlist = map { [ $_ => $hash{$_} ] } keys %hash
I need to see an example of what you would want to do with this, but so far I can see zero cause for using some big old module instead of basic Perl.
You can use map like this:
my $i = 0;
my %new_hash = map { $i ^= 1 ? new_key($_) : new_val($_) } %hash;
You can use mapn
from my module List::Gen to do this:
use List::Gen 'mapn';
my %new_hash = mapn {new_key($_[0]) => new_value($_[1])} 2 => %old_hash;
mapn
is like map, except it it takes an additional argument, the number of elements to walk the list by. Inside the block, the @_
array is set to the current slice.
$ perl -d /dev/null
DB<2> %p = ( a=>'b', c=> 'd');
DB<5> p Dumper \%p
$VAR1 = {
'c' => 'd',
'a' => 'b'
};
To e.g. reverse the key and the value:
DB<6> %q = map { ($p{$_}, $_ ) } keys %p
DB<7> p Dumper \%q
$VAR1 = {
'b' => 'a',
'd' => 'c'
};
As of perl 5.20, core utility List::Util::pairmap
does exactly that:
use List::Util qw(pairmap);
my %new_hash = pairmap { new_key($a) => new_val($b) } %hash;
It's not necessarily optimal (as it involves unrolling the hash to a list and back) but I believe this is the shortest way in vanilla perl.
精彩评论