2017-05-30 43 views
0

我在Perl中擁有多維散列值。在多維散列Perl中搜索第一級密鑰

其結構

$hash{$key}{$field}{$date} = $value; 

考慮到我有正確的價值和現場兩種。

什麼是最快的過程中可以搜索鑑於其關鍵在於本身的價值是唯一的(有一個1-1關係的關鍵)

編輯:

我已經增加了第三級,其是日期。 並非所有的日期都有價值,但是當它有時,它會在所有日期之間共享。

爲了簡化它,如果它有一個值,它是「A」,否則是空白的。

問候, InnZaayynn

+0

'$哈希{$ _} {$字段}當量$值和打印「=> $ _ \ n「爲鍵%hash;'如果你正在尋找第一級密鑰。 –

+0

可能希望在那裏打印並保存。 – Sobrique

+0

是的,並定期foreach與塊也(可能會有多個第一級滿足條件的關鍵)。 –

回答

4

您的數據組織形式不適合做一個快速搜索。你將不得不遍歷整個散列。如果您要執行多次搜索,最好是生成「反向」散列,因此您只需要遍歷整個散列,而不是每次搜索一次。


如果是執行多次搜索,而且他們並不都是相同的字段,產生反散如下:

my %key_by_field_and_value; 
for my $key (keys(%hash)) { 
    my $hash_for_key = $hash{$key}; 
    for my $field (keys(%$hash_for_key)) { 
     my $hash_for_key_and_field = $hash_for_key->{$field}; 
     defined(my $date = get_any_one_key($hash_for_key_and_field)) 
     or next; 

     length(my $value = $hash_for_key_and_field->{$date}) 
     or next; 

     $key_by_field_and_value{$field}{$value} = $key; 
    } 
} 

然後,搜索變得

my $field  = ...; 
my $target_value = ...; 

if (defined(
    my $target_key = 
     do { no autovivification; $key_by_field_and_value{$field}{$target_value} } 
)) { 
    ... 
} 

如果您正在執行多個搜索,並且它們都是相同的字段,請按如下所示生成逆散列:

my $field = ...; 

my %key_by_value; 
for my $key (keys(%hash)) { 
    my $hash_for_key = $hash{$key}; 
    defined(my $hash_for_key_and_field = $hash_for_key->{$field}) 
     or next; 

    defined(my $date = get_any_one_key($hash_for_key_and_field)) 
     or next; 

    length(my $value = $hash_for_key_and_field->{$date}) 
     or next; 

    $key_by_value{$value} = $key; 
} 

然後,搜索變得

my $target_value = ...; 

if (defined(my $target_key = $key_by_value{$target_value})) { 
    ... 
} 

如果你只是想搜索一次,你就必須搜索整個哈希。

my $field  = ...; 
my $target_value = ...; 

my $target_key; 
for my $key (keys(%hash)) { 
    my $hash_for_key = $hash{$key}; 
    defined(my $hash_for_key_and_field = $hash_for_key->{$field}) 
     or next; 

    defined(my $date = get_any_one_key($hash_for_key_and_field)) 
     or next; 

    length(my $value = $hash_for_key_and_field->{$date}) 
     or next; 

    if ($value eq $target_value) { 
     $target_key = $key; 
     last; 
    } 
} 

if (defined($target_key)) { 
    ... 
} 

上述兩種解決方案都使用的my ($key) = keys(%$h);這個有效的版本:

sub get_any_one_key { 
    my ($h) = @_; 
    my $key = each(%$h); 
    keys(%$h); # Reset iterator 
    return $key; 
}