2

私は次のような構造を持っています(ハッシュのハッシュ):

$VAR1 = {
          'Lee2000a' => {
                'abstract' => 'Abstract goes here',
                'author' => 'Lee, Wenke and Stolfo, Salvatore J'
                'title' => 'Data mining approaches for intrusion detection'
                'year' => '2000'
              },
          'Forrest1996' => {
                'abstract' => 'Abstract goes here',
                'author' => 'Forrest, Stephanie and Hofmeyr, Steven A. and Anil, Somayaji'
                'title' => 'Computer immunology'
                'year' => '1996'
                }
        };

この構造を 3 つの条件に従って (この順序で) 並べ替えたいと思います。

1 番目 - 年値 (1996,2000) による 2 番目 - 「外部」(Lee2000a、Forrest1996) 構造キーによる 3 番目 - 「内部」構造キー (要約、著者、タイトル、年) によるアルファベット順。

これまでのところ、何らかの方法で組み合わせる必要がある 2 つのコードがあります。

I. コードは 2 番目と 3 番目の基準を満たしています

for $i (sort keys(%bibliography)){
   print "$i => ", "\n";
   for $j (sort keys ($bibliography{"$i"})){
   print "\t $j -> ", $bibliography{"$i"}{"$j"},"\n";
   }
} 

Ⅱ.コードは最初の条件を満たしています

for $i (sort { ($bibliography{$a}->{year} || 0) <=> ($bibliography{$b}->{year} || 0) } keys %bibliography){
  print "$i => ", "\n";
  for $j (sort keys ($bibliography{"$i"})){
    print "\t $j -> ", $bibliography{"$i"}{"$j"},"\n";
  }
}

どうもありがとうございました

4

2 に答える 2

8

いくつかの二次条件で並べ替えるには、論理 OR を使用できます。

my @sorted = sort {
                 $a{c1} <=> $b{c1} || 
                 $a{c2} <=> $b{c2}
             } @unsorted

この例では@unsorted、キーc1でハッシュをソートし、この比較が等しい場合はキーでソートしますc2

目的のために、この方法で外側のループの 2 つの並べ替え比較を組み合わせて、並べ替えブロックが次のようになるようにすることができます。

(($bibliography{$a}->{year} || 0) <=> ($bibliography{$b}->{year} || 0)) ||
($a cmp $b)
于 2012-12-10T13:26:39.677 に答える
2

[更新]ソート条件でバッシュされた入力ハッシュのキーを単純に返す、より単純なバージョンが追加されました。

1 番目のアプローチ: ソートされたリストを返す

ハッシュをソートしたいのですが、ソート条件にはキーと値にネストされたものの両方が含まれます。$aそれぞれとを比較できる1 パスの並べ替えを行うには$b、ハッシュ内の各キーと値を使用できるようにするハッシュ aa リストを変換すると便利な場合があります。

少し無駄ですが、動作します:

my @sorted = 
 sort {
    $a->{val}->{year} <=> $b->{val}->{year} ||             # 1st condition
    $a->{key} <=> $b->{key} ||                             # 2nd condition
    $a->{val}->{abstract} <=> $b->{val}->{abstract} ||     # 3rd condition
    $a->{val}->{author} <=> $b->{val}->{author} ||         # (not really sure
    $a->{val}->{title} <=> $b->{val}->{title} ||           # how you wanted this
    $a->{val}->{year} <=> $b->{val}->{year}
  } map { { val => $biblio{$_}, key => $_  }  } keys %biblio;

ハッシュをソートしています。戻り値としてリストが必要です。その場合、どこにForrest1996適合しLee2000aますか?ハッシュを、それぞれ aと aの 2 つのプロパティを持つハッシュのリストに変換するのが理にかなっていると思いました。keyval

したがって、ソートの戻り値は、次のようなハッシュのリストになります。

@sorted = (
      {
        'val' => {
                   'title' => 'Computer immunology',
                   'author' => 'Forrest, Stephanie and Hofmeyr, Steven A. and Anil, Somayaji',
                   'abstract' => 'Abstract goes here',
                   'year' => 1996
                 },
        'key' => 'Forrest1996'
      },
      {
        'val' => {
                   'title' => 'Data mining approaches for intrusion detection',
                   'author' => 'Lee, Wenke and Stolfo, Salvatore J',
                   'abstract' => 'Abstract goes here',
                   'year' => 2000
                 },
        'key' => 'Lee2000a'
      }
  )

2 番目のアプローチ: 並べ替え条件に基づいてキーのリストのみを返す

コメントを読んで再考した後、入力ハッシュのキーを返すだけで十分で軽量だと思います。

my @sorted = 
  sort {
    $biblio{$a}->{year} <=> $biblio{$b}->{year} ||         # 1st condition
    $a <=> $b ||                                           # 2nd condition
    $biblio{$a}->{abstract} <=> $biblio{$b}->{abstract} || # 3rd condition
    $biblio{$a}->{author} <=> $biblio{$b}->{author}        # ...and so on
   } keys %biblio;

そのまま帰る・・・

 @sorted = (
      'Forrest1996',
      'Lee2000a'
 );
于 2012-12-10T13:35:29.433 に答える