2015-10-18 52 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

聽起來像你問你是否可以更改密鑰(即解碼它)而不刪除原始元素並重新插入它。如果是這樣,答案是否定的。對於散列,數學函數(哈希函數)將密鑰轉換爲索引。更改密鑰可以更改索引,因此更改密鑰需要將值從舊索引移動到新索引,因此更改密鑰需要刪除和重新插入值。