2017-05-30 36 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; 
}