2012-03-13 11 views
1

私はPerlコードを持っている、:その1が入力されると、ちょうど$h任意の変数は、使用しないように上記のコードを最適化する最適化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"; 
       } 
      } 
      } 
     } 

ことは可能ですか?ここで

+0

サンプル入力ハッシュ構造を指定できますか? –

答えて

4

はそれで私の亀裂です:

print $$_->{value}{src}, "\n" for grep { 
    ref $_ eq 'JE::Object::Proxy' && 
    $$_->{class_info}{name} eq 'HTMLImageElement' 
} map { 
    values %$_ 
} values %{ $h->[1] }; 
+0

うわー!ニースコード! –

0

ただ、ヘルパー変数を削除することは簡単ですが、このようなものは、それを行う必要があります。

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"; 
     } 
    } 
    } 
} 

しかし、私はそれをより読みやすくする方法は実際にはわかりません.3次元構造の反復です。

+2

ヒント:手続き型から宣言型に切り替えることにより、ほとんどの場合、コードはより読みやすくなります。 [Data :: DPath](http://p3rl.org/Data::DPath)は、Perlのデータ構造に潜んでいます.XPathはXMLの場合と同様です。 – daxim

3

「厄介」の多くは、行数を減らし、ネストしたコードの量を最小限に抑えることによって、きれいにすることができます。 eachコマンドを使用して、次のキーとその関連値をハッシュから1行で取得します。 [編集:Axemanが指摘したように、あなたは本当に値が必要なので、eachの代わりにvaluesを使用します。また、printステートメントをスキップするには、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

+1これは私がしばらくそれを見つめなければ理解できる唯一の解決策です。よくやった – Borodin

3

あなたは実際には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}; 
    } 
}