2015-10-18 47 views
1

有一个Hash::MultiValue对象。 keysvalues可能是utf8编码的字节串。需要解码它们inplaceDecode Hash :: MultiValue in perl

下面我想要做什么:

use 5.014; 
use warnings; 
use Hash::MultiValue; 
use Encode; 

my $hm = make_demo_data(); # the $hm is Hash::MultiValue 
          # the keys and values are utf8 encoded byte-strings 
$hm->each(sub { print "$_[0]: $_[1]\n" }); 

decodehm($hm); #decode the $hm inplace 

say "--decoded--";  
binmode(STDOUT, ':utf8'); 
$hm->each(sub { print "$_[0]: $_[1]\n" }); 

sub decodehm { 
    my $hm = shift; 
    #make copy - but decoded 
    my $new = Hash::MultiValue->new(map Encode::decode_utf8($_), $hm->flatten); 
    $hm->clear; #clear the original 
    $new->each(sub { $hm->add($_[0], $_[1]) }); #set each element in the original $hm 
} 

sub make_demo_data { #utf8 encoded byte-strings 
    return Hash::MultiValue->new(
     "k1\x{c3}\x{a1}" => "v1a\x{c3}\x{a1}", 
     "k1\x{c3}\x{a1}" => "v1b\x{c3}\x{a1}", 
     "k2a" => "v2aa", 
     "k3\x{c3}\x{a1}" => "v3a\x{c3}\x{a1}", 
    ); 
} 

如。在UTF8终端打印出想要的结果

k1á: v1aá 
k1á: v1bá 
k2a: v2aa 
k3á: v3aá 
--decoded-- 
k1á: v1aá 
k1á: v1bá 
k2a: v2aa 
k3á: v3aá 

不过分decodehm - 是不是“好”。可以以更“优雅”的形式解决问题吗?

回答

2

听起来像你问你是否可以更改密钥(即解码它)而不删除原始元素并重新插入它。如果是这样,答案是否定的。对于散列,数学函数(哈希函数)将密钥转换为索引。更改密钥可以更改索引,因此更改密钥需要将值从旧索引移动到新索引,因此更改密钥需要删除和重新插入值。