Perl的哈希值排序和比较它

问题描述:

我的数据结构是Perl的哈希值排序和比较它

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

print Dumper \%hash; 

我想作为排序依据的三键的哈希值。即1,23,在这种情况下为 ,然后比较阵列中的第二个元素(index[1])。如果它们是相同的,然后打印出来。

预期排序的散列:

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

print Dumper \%hash; 

排序散后,我们比较了第1个数组[3,4]与第二阵列[9,2]index[1]4不等于2,所以我们不打印任何东西。

然后,我们比较第二个数组[9,2]index[1]与第三个数组[4,2]2等于2,那么我们要打印的是

firstkey, secondkey, 3, [8,2]

的所有内容,我们只需要在邻接的阵列进行比较。

我读了很多有关排序哈希的解决方案,但我找不到一个真正重新排序的解决方案是否有任何方法通过密钥重新排序哈希,并用Perl中的新顺序构造哈希? 或者我们只能使用for循环对散列进行排序,并在for循环中进行比较?

+5

你不能“_sort hash_” - 它们本质上是无序的。但是你可以得到一个有序的键列表,使用你希望的标准在散列键列表中使用'sort'。然后你有一个_ordered_列表的键来迭代,所以你可以使用你的散列“排序方式”。查看[这篇文章](https://*.com/a/45338396/4653379)排序一个类似的哈希,或[这篇文章](https://*.com/a/45928281/4653379)多一点涉及到一些评论。那里有很多东西。 – zdim

+0

@zdim感谢您的建议。我正在尝试。 – Luke

+0

尽管上面的评论总体上很好,并且值得关注,但它可能无助于解决这个问题(因此可能会产生误导) - 我发布了一个答案。 – zdim

一个不能有一个“排序的散列” –它们在本质上无序的数据结构(见keys)。初始种子和散列遍历的randomizaton甚至是enhanced for security purposes

但是我们可以根据需要对散列键列表进行排序。然后我们有一个有序列表进行迭代,从而可以按“排序方式”处理哈希。

在这里排序的关键是在更深层次,所以遍历上(两个)层次来达到它们。然后,它是一个简单的排序和测试

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

的几个注意事项

  • 排序键遍历开始第二个由于比较标准

  • Hashref在被复制第二级只是为了方便,才能减轻凌乱的语法

  • 当复杂的数据结构过于笨重这可能是时间使用类,而不是

这适用于在这两个级别的任何数字键(只需一个键显示为每个级别)。

+0

非常简单直接的解决方案。谢谢你的帮助 – Luke

如前所述,您将无法指定散列的顺序。这里有一种方法可以将它映射到可以排序的东西,并进行所需的比较。

#!/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]; 
    } 
}