Reputation: 1261
Given the following hash:
%errors = (
"2013-W9 -> 2013-W12" => 1,
"2013-W5 -> 2013-W8" => 1,
"2013-W13 -> 2013-W15" => 1
)
I'm trying to sort it like this (so I can use it in a foreach
loop):
%errors = (
"2013-W5 -> 2013-W8" => 1,
"2013-W9 -> 2013-W12" => 1,
"2013-W13 -> 2013-W15" => 1
)
I've tried sort keys %errors
and sort{$a <=> $b) keys %errors
without success.
How can I fix this problem?
Upvotes: 2
Views: 1485
Reputation: 1665
I had a similar kind of situation. I solved my problem in the below way:
You tried with
sort keys %errors
and
sort{$a <=> $b) keys %errors
Just try almost a similar thing with a little difference:
my %errors = (
"2013-W9 -> 2013-W12" => 1,
"2013-W5 -> 2013-W8" => 1,
"2013-W13 -> 2013-W15" => 1);
foreach my $val(sort {my ($anum) = ($a =~ /\d+-\w(\d+)$/); my ($bnum) = ($b =~ /\d+-\w(\d+)$/); $anum <=> $bnum} keys %error
{
print "$val\n";
}
In the above example I have printed the keys only.
Output:
2013-W5 -> 2013-W8
2013-W9 -> 2013-W12
2013-W13 -> 2013-W15
Upvotes: 0
Reputation:
At The Alphanum Algorithm there's a general string sort routine that compares numeric substrings as numbers, implemented in many languages including Perl.
Upvotes: 2
Reputation: 4581
It seems that in this case the CPAN module Sort::Naturally
works fine:
use Sort::Naturally qw(nsort);
say $_ for nsort keys %errors;
Upvotes: 4
Reputation: 69284
It's not entirely clear what sort order you want, but this approach can easily be extended:
#!/usr/bin/perl
use strict;
use warnings;
use 5.010;
my %errors = (
"2013-W9 -> 2013-W12" => 1,
"2013-W5 -> 2013-W8" => 1,
"2013-W13 -> 2013-W15" => 1
);
my @sorted_keys = map { $_->[0] }
sort { $a->[1] <=> $b->[1] }
map { [ $_, /W(\d+)/ ] } keys %errors;
say $_ for @sorted_keys;
Upvotes: 2
Reputation: 50647
Keys will be sorted for yyyy-Wx
in ascending order; first by comparing yyyy
and then x
numbers,
my @sorted_keys = map $_->[0],
sort {
$a->[1] <=> $b->[1]
||
$a->[2] <=> $b->[2]
}
map [ $_, /(\d+)/g ],
keys %errors;
Upvotes: 1