开发者

map for hashes in Perl

开发者 https://www.devze.com 2023-02-28 14:43 出处:网络
开发者_C百科Is there a hash equivalent for map? my %new_hash = hash_map { new_key($a) => new_val($b) } %hash;

开发者_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.

0

精彩评论

暂无评论...
验证码 换一张
取 消