我有一个看起来像这样的数据结构(散列):
$VAR1 = {
'masterkeyB' => {
'D' => ['b', 'c', 'a'],
'A' => ['b', 'a', 'c'],
'C' => ['a', 'c', 'b'],
'B' => ['a', 'c', 'b'],
},
'masterkeyA' => {
'B' => ['a', 'c', 'b'],
'C' => ['a', 'c', 'b'],
'A' => ['b', 'a', 'c'],
'D' => ['b', 'c', 'a'],
}
};
我想按字母顺序对该结构进行排序:
$VAR1 = {
'masterkeyA' => {
'A' => ['a', 'b', 'c'],
'B' => ['a', 'b', 'c'],
'C' => ['a', 'c', 'b'],
'D' => ['a', 'b', 'c'],
},
'masterkeyB' => {
'A' => ['a', 'b', 'c'],
'B' => ['a', 'b', 'c'],
'C' => ['a', 'c', 'b'],
'D' => ['a', 'b', 'c'],
}
};
请注意,除“ C”外,所有数组均已排序。
答案 0 :(得分:1)
只需遍历嵌套循环中的键,对遇到的值进行排序。编辑:请参阅http://p3rl.org/dsc#HASHES-OF-HASHES
use feature qw(postderef);
use Tie::Hash::Indexed qw();
my $unsorted = {
'masterkeyB' => {
'D' => ['b', 'c', 'a'],
'A' => ['b', 'a', 'c'],
'C' => ['a', 'c', 'b'],
'B' => ['a', 'c', 'b'],
},
'masterkeyA' => {
'B' => ['a', 'c', 'b'],
'C' => ['a', 'c', 'b'],
'A' => ['b', 'a', 'c'],
'D' => ['b', 'c', 'a'],
}
};
tie my %sorted, 'Tie::Hash::Indexed';
for my $k1 (sort keys $unsorted->%*) {
for my $k2 (sort keys $unsorted->{$k1}->%*) {
my $v = $unsorted->{$k1}{$k2};
$v = [sort $v->@*] unless 'C' eq $k2;
$sorted{$k1}{$k2} = $v;
}
}
__END__
$HASH1 = {
masterkeyA => {
A => ['a', 'b', 'c'],
B => ['a', 'b', 'c'],
C => ['a', 'c', 'b'],
D => ['a', 'b', 'c']
},
masterkeyB => {
A => ['a', 'b', 'c'],
B => ['a', 'b', 'c'],
C => ['a', 'c', 'b'],
D => ['a', 'b', 'c']
}
};
答案 1 :(得分:1)
与数组不同,perl中的哈希不会保持排序顺序,因此常见的范例是在遍历数据结构时对哈希键进行排序。您需要的基本代码段是
for my $k ( sort keys %hash ) {
for my $sk ( sort keys %{$hash->{$k}} ) {
# do something
}
}
以排序顺序访问哈希键,并且
if ( $k ne 'KEY' ) {
# sort this array
$hash->{$k} = sort @{$hash->{$k}}
}
对数组进行选择性排序。
例如,假设您要打印散列:
use strict;
use warnings;
use feature ':5.16';
my $data = {
'masterkeyB' => {
'D' => ['b', 'c', 'a'],
'A' => ['b', 'a', 'c'],
'C' => ['a', 'c', 'b'],
'B' => ['a', 'c', 'b'],
},
'masterkeyA' => {
'B' => ['a', 'c', 'b'],
'C' => ['a', 'c', 'b'],
'A' => ['b', 'a', 'c'],
'D' => ['b', 'c', 'a'],
}
};
for my $mk ( sort keys %$data ) {
say $mk;
for my $letter ( sort keys %{$data->{$mk}} ) {
say ' ' . $letter;
if ( $letter eq 'C') {
say ' [ ' . join(", ", @{$data->{$mk}{$letter}}) . ' ]';
}
else {
say ' [ ' . join(", ", sort @{$data->{$mk}{$letter}}) . ' ]';
}
}
}
结果:
masterkeyA
A
[ a, b, c ]
B
[ a, b, c ]
C
[ a, c, b ]
D
[ a, b, c ]
masterkeyB
A
[ a, b, c ]
B
[ a, b, c ]
C
[ a, c, b ]
D
[ a, b, c ]
很明显,您可以更改say
行以执行您打算对此数据进行的任何操作。
答案 2 :(得分:0)
我认为这可以满足您的需求。不容易准备,但可以工作。
my %sorted;
map {my $key = $_; map {$sorted{$key}->{$_} = ($_ eq 'C' ? $hash{$key}->{$_} : [sort @{$hash{$key}->{$_}}])} keys %{$hash{$key}}} keys %hash;
或对原始哈希进行排序
map {my $key = $_; map {$hash{$key}->{$_} = ($_ eq 'C' ? $hash{$key}->{$_} : [sort @{$hash{$key}->{$_}}])} keys %{$hash{$key}}} keys %hash;
或更短的版本
map {my $key = $_; map {$hash{$key}->{$_} = [sort @{$hash{$key}->{$_}}] if($_ ne 'C')} keys %{$hash{$key}}} keys %hash;