Как я могу перебрать вложенный хэш хэша, не зная его ключа?
У меня есть хэш хэшей, то есть хэш и ссылки на хэш в моей структуре данных. Могу ли я выполнить итерацию самого глубокого хэша, когда у меня есть только имя основного хэша и нет ключа от самого глубокого хэша?
my %gates_info=(
'order' => {
'nand' => {
'nand2_1' =>2,
'nand2_5' =>-1,
'nand2_4' =>2,
'nand2_6' =>-1,
'nand2_2' =>2,
'nand2_3' =>3
},
'and' => {
'and2'=>1,
'and3'=>2,
},
}
);
sub max_gate_order {
print values (%{$gates_info{'order'}});
my @arr = (sort {$a <=> $b} values %{$gates_info{'order'}});
return $arr[-1];
}
Я хочу перебирать весь хэш, когда у меня есть только его имя%gates_info и нет ключей, таких как "nand" или "and". То, что я пытаюсь достичь, это получить самое высокое числовое значение в каждом из ворот путем сортировки. Например, 3 в случае nand и 2 в случае. Sub max_gate_order используется для сортировки и возврата наибольшего значения. Спасибо
3 ответа
Это более длинное, более излишнее решение, больше похоже на упражнение. Но вам может показаться интересным исследовать структуру итерации таким образом. (Я знаю, что знаю!) Это может быть полезно, если у вас есть только основное имя хеша (%gates_info
), и ни один из ключей под этим. Что именно подразумевает ваш вопрос, так и есть. Это вытягивает все имена ключей и значений настолько глубоко, насколько позволяет хеш, в случае, если любое из них может быть полезным. Я также загрузил рабочий пример. (Обратите внимание, что для этого нужно знать, насколько глубоким является ваш уровень хэша.)
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my %gates_info=(
'order' => {
'nand' => {
'nand2_1' =>2,
'nand2_5' =>-1,
'nand2_4' =>2,
'nand2_6' =>-1,
'nand2_2' =>2,
'nand2_3' =>3
},
'and' => {
'and2'=>1,
'and3'=>2,
},
}
);
print Dumper %gates_info;
print "\n\n";
my @gate;
my $hival;
foreach my $gate (sort keys %gates_info) {
foreach my $gatekey (sort keys %{$gates_info{$gate}}) {
foreach my $deepkey (sort keys %{$gates_info{$gate}{$gatekey}}) {
my $deepvalue = $gates_info{$gate}->{$gatekey}->{$deepkey};
push @gate, $deepvalue;
@gate = sort @gate;
$hival = $gate[@gate - 1];
print "Gate is $gate, gatekey is $gatekey, deepkey is $deepkey, deepvalue is $deepvalue\n";
}
print "\nGatekey is $gatekey, highest value is $hival\n\n";
@gate = (); #empty gate array
}
}
exit 0;
Вывод кода:
$VAR1 = 'order';
$VAR2 = {
'and' => {
'and2' => 1,
'and3' => 2
},
'nand' => {
'nand2_3' => 3,
'nand2_6' => -1,
'nand2_4' => 2,
'nand2_5' => -1,
'nand2_2' => 2,
'nand2_1' => 2
}
};
Gate is order, gatekey is and, deepkey is and2, deepvalue is 1
Gate is order, gatekey is and, deepkey is and3, deepvalue is 2
Gatekey is and, highest value is 2
Gate is order, gatekey is nand, deepkey is nand2_1, deepvalue is 2
Gate is order, gatekey is nand, deepkey is nand2_2, deepvalue is 2
Gate is order, gatekey is nand, deepkey is nand2_3, deepvalue is 3
Gate is order, gatekey is nand, deepkey is nand2_4, deepvalue is 2
Gate is order, gatekey is nand, deepkey is nand2_5, deepvalue is -1
Gate is order, gatekey is nand, deepkey is nand2_6, deepvalue is -1
Gatekey is nand, highest value is 3
keys
даст вам эти ключи.
sub max_gate_order {
my ($gates_info) = @_;
my $max_order;
my @gates;
for my $gate_type (keys %{ $gates_info->{order} }) {
for my $gate_id (keys %{ $gates_info->{order}{$gate_type} }) {
my $order = $gates_info->{order}{$gate_type}{$gate_id};
$max_order //= $order;
if ($order >= $max_order) {
if ($order > $max_order) {
$max_order = $order;
@gates = ();
}
push @gates, $gate_id;
}
}
}
return @gates;
}
my @gates = max_gate_order(\%gates_info);
Вышеуказанное возвращает все ворота с наивысшим порядком.
Если вы хотите и тип ворот, и идентификатор ворот, замените
push @gates, $gate_id;
с
push @gates, [ $gate_type, $gate_id ];
или же
push @gates, [ $gate_type, $gate_id, $order ];
sub max_gate_order {
my %hash =();
foreach my $k (keys %{$gates_info{'order'}}) {
my @arr = (sort {$a <=> $b} values %{$gates_info{'order'}->{$k}});
$hash{$k} = $arr[-1];
}
return \%hash;
}