Perl 当散列有多个键时,按值对其排序
我相信这就是通常按值对哈希进行排序的方式:Perl 当散列有多个键时,按值对其排序,perl,sorting,hash,Perl,Sorting,Hash,我相信这就是通常按值对哈希进行排序的方式: foreach my $key (sort { $hash{$a} <=> $hash{$b} } (keys %hash) ) { print "$key=>$hash{$key}"; } 如何按值排序并同时获取所有键?我只需创建一个新的哈希: my %new; for my $k1 (keys %hash) { for my $k2 (keys %{$hash{$k1}}) { for my $k3 (key
foreach my $key (sort { $hash{$a} <=> $hash{$b} } (keys %hash) ) {
print "$key=>$hash{$key}";
}
如何按值排序并同时获取所有键?我只需创建一个新的哈希:
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";
}
my%新建;
对于我的$k1(密钥%hash){
对于我的$k2(键%{$hash{$k1}}){
对于我的$k3(键%{$hash{$k1}{$k2}}){
$new{$k1,$k2,$k3}=$hash{$k1}{$k2}{$k3};
}
}
}
my@ordered=sort{$new{$a}$new{$b}}键%new;
我的$k(@ordered){
我的@keys=拆分($;,$k);
打印“key:@k-value:$new{$k}\n”;
}
这里有一种方法可以使用
我也做了类似的事情,将引用下移到适当的散列键。然后可以对指针执行排序 这样做的好处是,如果液位发生变化,很容易进行调整 我使用这种方法的目的是通过引用一组键来系统地将指针移动到特定级别。(例如:my@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";
}
my$list\u ref;
我的$pointer;
我的%list=(
值=>{
值2=>{
A=>“1”,
C=>“3”,
B=>“2”,
},
},
);
$list\u ref=\%list;
$pointer=$list_ref->{Value}->{Value2};
foreach my$键(排序{$pointer->{$a}$pointer->{$b}(键%{$pointer})){
打印“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 ]
)
当然,顺序肯定会有所不同。给定该列表,您可以在
{$a->[1]$b->[1]}
或类似位置对其排序,然后从@{$entry->[0]}
中为每个条目提取密钥路径。无论数据结构的深度如何,即使叶节点不是在同一深度出现,它都可以工作。但是,它需要一点扩展来处理不完全由hashref和普通标量组成的结构。因此,您希望在结构中进行无深度排序吗?此哈希中有3个键的固定深度,我希望根据存在的所有三元组键的值对哈希进行排序。谢谢,我只是用了这个。注意$
必须是一个从未出现在键中的值(默认为“\x1c”,一个控制字符),否则此代码将崩溃并烧掉。
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 ]
)