我面临着排序哈希数组的问题;哈希具有我需要排序的字母数字值。
请参阅此question!我的问题是这个问题的延伸。 我在上面的问题中尝试了解决方案,但没有得到所需的输出。
$arr_ref = [
{ brand => "A.1", PO => "1.a", supplier => "X" },
{ brand => "A.2", PO => "2.a", supplier => "X" },
{ brand => "B.1", PO => "1.b", supplier => "X" },
{ brand => "B.2", PO => "2.b", supplier => "X" },
{ brand => "B.3", PO => "1.c", supplier => "Y" },
]
我需要按品牌或PO排序。
#sort the array reference and place the array back into the standard_set
$arr_ref = [sort by_brand @$arr_ref];
sub by_brand {
$a->{brand} cmp $b->{brand}
}
复杂性是关键;可以从数字或字母字符开始。 品牌或PO也可以具有不同的尺寸。分隔符可以是点或超级。
我们可以根据$arr_ref
收到的输入来解决这个问题吗?
答案 0 :(得分:1)
你真的很亲密。您只需删除[
和]
括号,然后取消引用要分配给@$array_ref = ...
的数组。
use strict;
use warnings;
my $arr_ref = [
{ brand => "B.3", PO => "1.c", supplier => "Y" },
{ brand => "B.2", PO => "2.b", supplier => "X" },
{ brand => "B.1", PO => "1.b", supplier => "X" },
{ brand => "A.2", PO => "2.a", supplier => "X" },
{ brand => "A.1", PO => "1.a", supplier => "X" },
];
my @sorted = sort { $a->{brand} cmp $b->{brand} } @$arr_ref;
use Data::Dump;
dd @sorted;
输出:
(
{ brand => "A.1", PO => "1.a", supplier => "X" },
{ brand => "A.2", PO => "2.a", supplier => "X" },
{ brand => "B.1", PO => "1.b", supplier => "X" },
{ brand => "B.2", PO => "2.b", supplier => "X" },
{ brand => "B.3", PO => "1.c", supplier => "Y" },
)
答案 1 :(得分:1)
使用Schwartzian transform对其进行排序,并为每个字段更正比较器。
use strict;
use warnings;
use Data::Dumper;
my $arr_ref = [
{ brand => "A.1", PO => "1.a", supplier => "X" },
{ brand => "A.2", PO => "2.a", supplier => "X" },
{ brand => "B.1", PO => "1.b", supplier => "X" },
{ brand => "B.2", PO => "2.b", supplier => "X" },
{ brand => "B.3", PO => "1.c", supplier => "Y" },
];
my @sorted = map $_->[0], sort {
$a->[1][0] cmp $b->[1][0]
or $a->[1][1] <=> $b->[1][1]
or $a->[1][2] <=> $b->[1][2]
or $a->[1][3] cmp $b->[1][3]
} map [ $_, [ map split( /[.-]/, $_, 2 ), @$_{qw(brand PO)} ] ],
@$arr_ref;
print Dumper( \@sorted );
尝试使用品牌"A.10"
来发现差异。
答案 2 :(得分:1)
尝试这种排序方法:
sub by_brand_or_po {
my ($a_ba, $a_bn) = split /\.|-/, $a->{brand};
my ($b_ba, $b_bn) = split /\.|-/, $b->{brand};
my ($a_pa, $a_pn) = split /\.|-/, $a->{PO};
my ($b_pa, $b_pn) = split /\.|-/, $b->{PO};
return( $a_ba cmp $b_ba or $a_bn <=> $b_bn or
$a_pa cmp $b_pa or $a_pn <=> $b_pn );
}
它优先考虑PO数字上的品牌alpha优于PO数字上的数字,并将分割为点或连字符。
答案 3 :(得分:0)
use Sort::Key::Natural qw(natkeysort);
my @sorted_by_brand = natkeysort { $_->{brand} } @data;
my @sorted_by_po = natkeysort { $_->{po} } @data;