Sort by mmyy (month and year)

I am looking for a logical (not an optional module) to sort by this format. I have a list of strings that looks like this:

asdadasBBBsfasdasdas-0112
asdanfnfnfnfnf222ads-1210

etc .. I can’t just sort by numbers, because, for example: 812> 113 (812 = August 2012, 113 = January 2013, so its incorrect)

any good strategy

thank,

+5
source share
5 answers

The Schwartz transformation would be a huge waste here. This similar construction, whose name I will never remember, would be better.

my @sorted =
   map substr($_, 4),
    sort
     map substr($_, -2) . substr($_, -4, 2) . $_,
      @unsorted;

Using the match operator instead of substr:

my @sorted =
   map substr($_, 4),
    sort
     map { /(..)(..)\z/s; $2.$1.$_ }
      @unsorted;
+5
source

What about the Schwartz transform :

#!/usr/bin/perl
use strict;
use warnings;
use Data::Dump qw(dump);

my @list = (
    'asdadasBBBsfasdasdas-0112',
    'asdanfnfnfnfnf222ads-1210',
    'asdanfnfnfnfnf222ads-1211',
    'asdanfnfnfnfnf222ads-1010',
    'asdanfnfnfnfnf222ads-1011',
);

my @sorted = 
    map  { $_->[0] }
    sort { $a->[1] <=> $b->[1] or $a->[2] <=> $b->[2] }
    map  { /-(\d\d)(\d\d)$/; [$_, $2, $1] } @list;
dump @sorted;

output:

(
  "asdanfnfnfnfnf222ads-1010",
  "asdanfnfnfnfnf222ads-1210",
  "asdanfnfnfnfnf222ads-1011",
  "asdanfnfnfnfnf222ads-1211",
  "asdadasBBBsfasdasdas-0112",
)
+5
source

, , :

sub mmyy_sorter {

    my $a_yy = substr($a, -2);
    my $b_yy = substr($b, -2);

    my $a_mm = substr($a, -4, 2);
    my $b_mm = substr($b, -4, 2);

    return ($a_yy cmp $b_yy) || ($a_mm cmp $b_mm);
}

my @sorted = sort mmyy_sorter @myarray;

NB: , , , .

You could also use automatic Perl type conversion and use the operator <=>instead cmp, since all values ​​actually represent numbers.

+2
source

How about redoing it for a few months? For instance:

812 = 12 * 12 + 8

113 = 13 * 12 + 1

You can turn years into months, and that will be good. You can use regular expression to select numbers.

0
source

Thanks @ M42 for sample data.

use strict;
use warnings;
use feature 'say';

my @list = (
    'asdadasBBBsfasdasdas-0112',
    'asdanfnfnfnfnf222ads-1210',
    'asdanfnfnfnfnf222ads-1211',
    'asdanfnfnfnfnf222ads-1010',
    'asdanfnfnfnfnf222ads-1011',
);

my @sorted = sort {
  my ($aa, $bb) = map { /(..)(..)\z/ and $2.$1 } $a, $b;
  $aa <=> $bb;
} @list;

say for @sorted;

Output

asdanfnfnfnfnf222ads-1010
asdanfnfnfnfnf222ads-1210
asdanfnfnfnfnf222ads-1011
asdanfnfnfnfnf222ads-1211
asdadasBBBsfasdasdas-0112
0
source

All Articles