Perl按三级键对哈希进行哈希排序并进行比较

时间:2017-09-21 20:53:27

标签: arrays perl sorting hash

我的数据结构是

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

print Dumper \%hash;

我想用第三个键对哈希进行排序。在这种情况下,即123 然后比较数组中的第二个元素(index[1])。如果它们是相同的,然后将其打印出来。

预期排序哈希:

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

print Dumper \%hash;

对哈希进行排序后,我们将第一个数组index[1]的{​​{1}}与第二个数组[3,4]进行比较。 [9,2]不等于4,因此我们不会打印任何内容。

然后,我们将第二个数组2的{​​{1}}与第三个数组index[1]进行比较。 [9,2]等于[4,2],然后我们将打印它的所有内容

2

我们只需要比较相邻的数组。

我读了很多关于排序哈希的解决方案,但我找不到真正重新排序的解决方案。是否可以通过密钥重新排序哈希并在Perl中使用新订单构造哈希? 或者我们只能通过使用for循环对哈希进行排序并在for循环中进行比较?

2 个答案:

答案 0 :(得分:3)

一个人不能拥有“排序哈希” - 它们本质上是无序的数据结构(参见keys)。初始种子和散列遍历的随机化甚至是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,以减轻凌乱的语法

  • 当复杂的数据结构过于笨拙时,可能需要使用类来代替

这适用于两个级别中的任意数量的键(每个级别只显示一个键)。

答案 1 :(得分: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];
    }
}