Оптимизировать Perl хэш беспорядок - PullRequest
1 голос
/ 14 марта 2012

У меня есть Perl-код, который выглядит беспорядочно:

         my $x = $h->[1];
         foreach my $y (keys %$x) {
           my $ax = $x->{$y};
           foreach my $ay (keys %$ax) {
             if (ref($ax->{$ay}) eq 'JE::Object::Proxy') {
               my $bx = $ax->{$ay};
               if ($$bx->{class_info}->{name} eq 'HTMLImageElement') {
                 print $$bx->{value}->{src}, "\n";
               }
             }
           }
         }

Можно ли оптимизировать приведенный выше код, чтобы не использовать какие-либо переменные, просто $h, поскольку этот вход является входным?

Ответы [ 4 ]

4 голосов
/ 14 марта 2012

Вот моя трещина:

print $$_->{value}{src}, "\n" for grep {
    ref $_ eq 'JE::Object::Proxy' &&
    $$_->{class_info}{name} eq 'HTMLImageElement'
} map {
    values %$_
} values %{ $h->[1] };
3 голосов
/ 14 марта 2012

Вы используете ключи, когда вы действительно хотите values.

foreach my $h ( grep { ref() eq 'HASH' } values %$x ) { 
    foreach my $obj ( 
        grep {   ref()                  eq 'JE::Object::Proxy' 
             and $_->{class_info}{name} eq 'HTMLImageElement' 
             } values %$h 
        ) { 
        say $obj->{value}{src};
    }
}
3 голосов
/ 14 марта 2012

Большую часть "беспорядка" можно устранить, уменьшив количество строк и уменьшив количество вложенного кода. Используйте команду each для получения следующего ключа и связанного с ним значения из хеша в одну строку. [ПРАВКА: как указал Аксеман, вам действительно нужны только значения, поэтому я заменяю использование each на values]. Также используйте пару операторов next, чтобы пропустить оператор печати. ​​

for my $ax (values %{$h->[1]} ) {
    for my $bx (values %$ax ) {
        next unless ref($bx) eq 'JE::Object::Proxy';
        next unless $$bx->{class_info}->{name} eq 'HTMLImageElement';
        print "$$bx->{value}->{src}\n";
    }
}
0 голосов
/ 14 марта 2012

Просто удалить вспомогательные переменные легко, что-то вроде этого должно сделать это:

foreach my $y (keys %{$h->[1]}) {
  foreach my $ax (%{$h->[1]->{$y}) {
    foreach my $ay (keys %$ax) {
      if(ref($h->[1]->{$y}->{$ay}) eq 'JE::Object::Proxy') {
        if($h->[1]->{$y}->{$ay}->{class_info}->{name} eq 'HTMLImageElement') {
          print $h->[1]->{$y}->{$ay}->{value}->{src}, "\n";
        }
      }
    }
  }
}

Вы также можете удалить дубликаты, если:

foreach my $y (keys %{$h->[1]}) {
  foreach my $ax (%{$h->[1]->{$y}) {
    foreach my $ay (keys %$ax) {
      if(ref($h->[1]->{$y}->{$ay}) eq 'JE::Object::Proxy' && $h->[1]->{$y}->{$ay}->{class_info}->{name} eq 'HTMLImageElement') {
        print $h->[1]->{$y}->{$ay}->{value}->{src}, "\n";
      }
    }
  }
}

Но я не оченьпосмотрим, как сделать его более читабельным: это итерация по трехмерной структуре.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...