2017-09-21 15 views
1

私のデータ構造は、私が第三の鍵でハッシュをソートしたい第3レベルキーによるハッシュのPerlのソート、ハッシュと

my %hash = (
    firstkey => { 
       secondkey => { 
          2 => ['9','2'], 
          1 => ['3','4'], 
          3 => ['8','2'] 
       } 
      } 
); 

print Dumper \%hash; 

でそれを比較します。すなわち1,2および3をこの場合 とし、配列内の2番目の要素(index[1])を比較してください。それらが同じ場合は、それを印刷してください。ソートされたハッシュ期待

:ソート、ハッシュ後

my %hash = (
    firstkey => { 
       secondkey => { 
          1 => ['3','4'], 
          2 => ['9','2'], 
          3 => ['8','2'] 
       } 
      } 
); 

print Dumper \%hash; 

は、我々は第二の配列[9,2]で第一配列[3,4]index[1]を比較します。 42と等しくないので、何も印刷しません。

次に、2番目の配列[9,2]index[1]と3番目の配列[4,2]を比較します。 2は、我々は唯一の隣接配列を比較する必要があり、それ

firstkey, secondkey, 3, [8,2]

のすべてのコンテンツを印刷しようとしている、2に等しいです。

私はハッシュのソートについて多くのソリューションを読んでいましたが、本当にそれを並べ替える解決策を見つけることができませんでした。キーでハッシュを並べ替え、新しい順序でハッシュを作成する方法はありますか? または、forループを使用してハッシュをソートし、forループで比較することはできますか?

+5

"_sort hash_"は本質的に順序付けられていません。しかし、あなたはキーのソートされたリストを取得することができます。あなたが望む任意の基準でハッシュのキーのリストに 'sort'を使います。しかし、あなたは、ソートされた方法でハッシュを使うことができるように、反復するキーの_ordered_リストを持っています。同様のハッシュを並べ替えるには[this post](https://stackoverflow.com/a/45338396/4653379)、もう少し詳しくは[this post](https://stackoverflow.com/a/45928281/4653379)を参照してください。いくつかのコメントと並べ替えを含む。そこにはもっとたくさんのことがあります。 – zdim

+0

@zdimご意見ありがとうございます。私はそれを試みている。 – Luke

+0

上記のコメントは一般的にうまくいっていますが、それに続く価値がありますが、この問題では役に立たない可能性があります(誤解を招く可能性があります)。 – zdim

答えて

3

一つは、彼らが本質的に順序付けられていないデータ構造(keysを参照)されている「ソートされたハッシュ」–を持つことはできません。最初のシードとハッシュトラバーサルのランダム化はenhanced for security purposesです。

しかし、必要に応じてハッシュキーのリストを並べ替えることができます。それから、反復処理するための順序付きリストがあり、したがって、ソートされた方法でハッシュを処理できます。

ここでソートするキーは、より深いレベルにあるため、上位(2つ)のレベルを反復して取得します。そして、それは簡単なソートとテスト

use warnings; 
use strict; 
use feature 'say'; 

my %hash = ( 
    firstkey1 => { 
     secondkey1 => { 
      2 => [9, 2], 1 => [3, 4], 3 => [8, 2] 
     } 
    } 
); 

foreach my $k1 (keys %hash) 
{ 
    foreach my $k2 (keys %{$hash{$k1}}) 
    { 
     # Relieve syntax below 
     my $hr = $hash{$k1}{$k2}; 

     my @sr_k3 = sort { $a <=> $b } keys %{$hr}; 

     foreach my $i (1..$#sr_k3) 
     { 
      if ($hr->{$sr_k3[$i]}[1] == $hr->{$sr_k3[$i-1]}[1]) 
      { 
       say "$k1, $k2, $sr_k3[$i], ", 
        '[', join(',', @{$hr->{$sr_k3[$i]}}), ']'; 
      } 
     } 
     #say "@{$hash{$k1}{$k2}{$_}}" for keys %{$hash{$k1}{$k2}}; 
    } 
} 

による

  • ハッシュリファレンスがでコピーされた比較基準に

    • ソートキーが第二1で始まる上で反復されているいくつかの注意事項があります便宜上、第2レベルは、乱雑な構文を緩和するために

    • 複雑なデータ構造は、これは(1つのキーだけがレベルごとに示されている)の両方のレベルでのキーの任意の数のために働く代わり

    をクラスを使用する時間であってもよいあまりに扱いにくい得ます。

  • +0

    簡単で簡単な解決法です。ご協力いただきありがとうございます – Luke

    0

    前述したように、ハッシュの順序を指定することはできません。ここでは、ソートして必要な比較を行うことができるものにマップする方法があります。

    #!/usr/bin/perl 
    use strict; 
    use warnings; 
    use Data::Dumper; 
    
    my %hash = (firstkey => { 
           secondkey => { 
            2 => [9,2], 
            1 => [3,4], 
            3 => [8,2], 
           } 
          } 
         ); 
    
    
    #obtain an array of two-element array refs, whose contents are the keys 
    #for the "secondkey" hash and the corresponding value, respectively 
    
    my @arr = map { [ $_, $hash{firstkey}->{secondkey}->{$_} ] } 
          keys %{$hash{firstkey}->{secondkey}}; 
    
    #sort on the aforementioned key 
    
    my @sorted = sort { $a->[0] <=> $b->[0] } @arr; 
    
    #obtain an array of array refs, whose contents are a pair of adjacent 
    #elements from the @sorted array 
    
    my @ordered_pairs = map { [ $sorted[$_], $sorted[$_+1] ] } 
            (0 .. (scalar @sorted - 2)); 
    
    #compare the elements in question, and do something if there's a match 
    
    for (@ordered_pairs) { 
        if ($_->[0][1][1] == $_->[1][1][1]) { 
         print Dumper $_->[1]; 
        } 
    } 
    
    関連する問題