我的数据结构是
my %hash = (
firstkey => {
secondkey => {
2 => ['9','2'],
1 => ['3','4'],
3 => ['8','2']
}
}
);
print Dumper \%hash;
我想用第三个键对哈希进行排序。在这种情况下,即1
,2
和3
然后比较数组中的第二个元素(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循环中进行比较?
答案 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];
}
}