我相信這是你會怎麼通常由值排序的哈希:排序按值散列當它有許多鍵
foreach my $key (sort { $hash{$a} <=> $hash{$b} } (keys %hash)) {
print "$key=>$hash{$key}";
}
這將打印出最小到最大的價值。
現在,如果我有這樣的哈希:
$hash{$somekey}{$somekey2}{$thirdkey}
我排序的價值觀和如何能得到所有的鑰匙呢?
我相信這是你會怎麼通常由值排序的哈希:排序按值散列當它有許多鍵
foreach my $key (sort { $hash{$a} <=> $hash{$b} } (keys %hash)) {
print "$key=>$hash{$key}";
}
這將打印出最小到最大的價值。
現在,如果我有這樣的哈希:
$hash{$somekey}{$somekey2}{$thirdkey}
我排序的價值觀和如何能得到所有的鑰匙呢?
我只是想創建一個新的哈希:
my %new;
for my $k1 (keys %hash) {
for my $k2 (keys %{$hash{$k1}}) {
for my $k3 (keys %{$hash{$k1}{$k2}}) {
$new{$k1,$k2,$k3} = $hash{$k1}{$k2}{$k3};
}
}
}
my @ordered = sort { $new{$a} <=> $new{$b} } keys %new;
for my $k (@ordered) {
my @keys = split($;, $k);
print "key: @k - value: $new{$k}\n";
}
這裏是一種使用Deep::Hash::Utils做到這一點。
use Deep::Hash::Utils qw(slurp);
my %h = (
A => {
Aa => { Aaa => 4, Aab => 5 },
Ab => { Aba => 1 },
Ac => { Aca => 2, Acb => 9, Acc => 0 },
},
B => {
Ba => { Baa => 44, Bab => -55 },
Bc => { Bca => 22, Bcb => 99, Bcc => 100 },
},
);
my @all_keys_and_vals = slurp \%h;
print "@$_\n" for sort { $a->[-1] <=> $b->[-1] } @all_keys_and_vals;
輸出:
B Ba Bab -55
A Ac Acc 0
A Ab Aba 1
A Ac Aca 2
A Aa Aaa 4
A Aa Aab 5
A Ac Acb 9
B Bc Bca 22
B Ba Baa 44
B Bc Bcb 99
B Bc Bcc 100
我已經做了通過移動參考升降到合適的哈希鍵類似的東西。然後你可以在指針上進行排序。
這樣做的好處是,如果級別改變,很容易調整。
我已經使用過這種方法,通過引用一組鍵來系統地將指針移動到特定的級別。 (例如:我的@Keys =('Value','Value2');)
我相信下面的例子的派生可能會給你你正在尋找的。
my $list_ref;
my $pointer;
my %list = (
Value => {
Value2 => {
A => '1',
C => '3',
B => '2',
},
},
);
$list_ref = \%list;
$pointer = $list_ref->{Value}->{Value2};
foreach my $key (sort { $pointer->{$a} <=> $pointer->{$b} } (keys %{$pointer})) {
print "Key: $key\n";
}
學術目的,這裏是一個相當整齊遞歸函數:
sub flatten_hash {
my ($hash, $path) = @_;
$path = [] unless defined $path;
my @ret;
while (my ($key, $value) = each %$hash) {
if (ref $value eq 'HASH') {
push @ret, flatten_hash($value, [ @$path, $key ]);
} else {
push @ret, [ [ @$path, $key ], $value ];
}
}
return @ret;
}
這需要像
{
roman => {
i => 1,
ii => 2,
iii => 3,
},
english => {
one => 1,
two => 2,
three => 3,
},
}
散列函數,並把它變成像
(
[ ['roman','i'], 1 ],
[ ['roman', 'ii'], 2 ],
[ ['roman', 'iii'], 3 ],
[ ['english', 'one'], 1 ],
[ ['english', 'two'], 2 ],
[ ['english', 'three'], 3 ]
)
列表
儘管當然t他的命令必然會有所不同。鑑於該列表,您可以將其排序在{ $a->[1] <=> $b->[1] }
或類似的位置,然後從每個條目的@{ $entry->[0] }
中提取關鍵路徑。無論數據結構的深度如何,即使葉節點不會全部出現在同一深度,它也可以工作。不過,它需要一點點的擴展來處理並非純粹使用hashrefs和純標量的結構。
所以,你想排序結構內的深度,而不管深度? – DavidO
這個散列中有3個鍵的固定深度,我想按照存在的所有鍵的三元組的值排序散列。 – petranaya