Search code examples
perlsortingnumericalalphabetical

perl - sort descending numerically, then alphabetically


Ok, here is task at hand: take a flat data file and sort the contents based on the numerical value of one of the elements of an array, then sort alphabetically (while preserving the descending numerical sort order).

Data file is something like this:

data1*oranges*3
data2*zebras*23
data3*apples*456
data4*pears*2
data5*orangutans*3
data6*peaches*1

So we want output to be:

data3*apples*456
data2*zebras*23
data1*oranges*3
data5*orangutans*3
data4*pears*2
data6*peaches*1

I'm at a loss and can't really find anything that addresses what I need to do here. I'd appreciate anyone's input in solving this.


Solution

  • First, separate the string into the parts you want to compare. Then, compare the parts.

    my @sorted = sort {
       my @fields_a = split /\*/, $a;
       my @fields_b = split /\*/, $b;
       $fields_b[2] <=> $fields_a[2] || $fields_a[1] cmp $fields_b[1]
    } @unsorted;
    

    Less repeated work:

    my @sorted =
       map $_->[0],
       sort { $b->[3] <=> $a->[3] || $a->[2] cmp $b->[2]
       map [ $_, split /\*/ ],
       @unsorted;