Прогулка по хешу (дерево, что угодно) - это техника, которую должен знать любой программист. rafl использует модуль посетителя , но в некоторых случаях я думаю, что лечение почти хуже, чем болезнь.
Является ли ваш ожидаемый результат тем, что вы хотели?Кажется, это отличается от того, что вы сказали в тексте, как FM говорит .Я использую его хеш в своем примере.
Это довольно легко, если вы используете очередь.Вы начинаете с хэша верхнего уровня.Каждый раз, когда вы сталкиваетесь с хэш-ссылкой, вы добавляете ее в очередь.Когда вы запускаете массив ref, вы проверяете, есть ли у него значения, и удаляете этот ключ, если его нет.Все остальное вы оставляете в покое:
#!perl
use strict;
use warnings;
use 5.010;
my %hash = ( # From FM
'A' => {
'B' => ['C', 'D', 'E'],
'F' => {
'G' => [],
'H' => [],
'Z' => ['FOO', 'BAR'], # Not in the OP's original.
},
'I' => [],
},
);
my @queue = ( \%hash );
while( my $ref = shift @queue ) {
next unless ref $ref eq ref {};
KEY: foreach my $key ( keys %$ref ) {
if( ref $ref->{$key} eq ref {} ) {
push @queue, $ref->{$key};
next KEY;
}
elsif( ref $ref->{$key} eq ref [] ) {
delete $ref->{$key} if @{$ref->{$key}} == 0;
}
}
}
use Data::Dumper;
print Dumper( \%hash );
Мой вывод:
$VAR1 = {
'A' => {
'F' => {
'Z' => [
'FOO',
'BAR'
]
},
'B' => [
'C',
'D',
'E'
]
}
};
Этот вывод звучит больше как то, что вы просите, а не как указанная вами реорганизация.Вы можете уточнить вывод?