Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Re: Data with Letter(s) & Number sort query

by Laurent_R (Canon)
on Nov 19, 2016 at 10:11 UTC ( [id://1176136]=note: print w/replies, xml ) Need Help??


in reply to Data with Letter(s) & Number sort query

Using a regex to separate the letters from the digits, and then sorting numerically on the digits, and finally putting back the pieces together:
$ perl -e 'use strict; > use warnings; > use Data::Dumper; > > my @a = qw / E1180 D250 A1180 E855 E975 A130 A250 B1105 B1255 B2480 +C1180 C1600 D1180 /; > > print "$_\n" > for map "$_->[0]$_->[1]", > sort { $a->[1] <=> $b->[1]} > map { /([A-Z]+)(\d+)/; [$1, $2]} @a;' A130 D250 A250 E855 E975 B1105 E1180 A1180 C1180 D1180 B1255 C1600 B2480
Note that you did not specify any sort order for the letters when the digits are the same, so the items are kept in the original order in that case (see e.g. A1180, C1180 and D1180).

Update:: removed a piece a code that got accidentally pasted twice.

Replies are listed 'Best First'.
Re^2: Data with Letter(s) & Number sort query
by Anonymous Monk on Nov 19, 2016 at 10:46 UTC
    Thank you for the quick suggestions. I too will be interested to hear the answer about padded.
    I want the Letter part to be sorted as normal alphabetical order (possibly from z to a as an option) - also as another option it could be good to ignore the case of the letters.
    The letter part sort comes before the number part.
      If you want to the letters to be a secundary sort key, you can try this:
      $ perl -e 'use strict; > use warnings; > use Data::Dumper; > > my @a = qw / E1180 D250 A1180 E855 E975 A130 A250 B1105 B1255 B2480 +C1180 C1600 D1180 /; > > print "$_\n" > for map "$_->[0]$_->[1]", > sort { $a->[1] <=> $b->[1] || $a->[0] cmp $b->[0]} > map { /([A-Z]+)(\d+)/; [$1, $2]} @a; > ' A130 A250 D250 E855 E975 B1105 A1180 C1180 D1180 E1180 B1255 C1600 B2480
      Notice that A250 and D250 are now sorted alphabetically on the initial letter. For a reverse alphabetical order on the letters, change the sort line to this:
      sort { $a->[1] <=> $b->[1] || $b->[0] cmp $a->[0]}
      I did not have time before to give a complete answer to your questions, but if you want upper and lower case letters and ignore case for the sort:
      $ perl -e 'use strict; > use warnings; > > my @a = qw / d1180 a1180 E1180 D250 A1180 E855 E975 A130 A250 B1105 +b1255 b2480 c1180 c1600 e855 e975 a130 A250 B1105 B1255 B2480/; > > print "$_\n" > for map "$_->[0]$_->[1]", > sort { $a->[1] <=> $b->[1] || uc $a->[0] cmp uc $b->[0]} > map { /([a-zA-Z]+)(\d+)/; [$1, $2]} @a;' A130 a130 A250 A250 D250 E855 e855 E975 e975 B1105 B1105 a1180 A1180 c1180 d1180 E1180 b1255 B1255 c1600 b2480 B2480
      The letter part sort comes before the number part.
      Not sure what you mean.
        That is very useful but not quite what I wanted.
        In your output, the primary sort are the numbers and the secondary are the letters.
        I wanted it the other way around. Therefore all the data with A or a at the front would come before the data with B and so on. Therefore it would be (to start)
        A130 a130 A250 A250 A1180 B1105 b1255 B2480 etc

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1176136]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others contemplating the Monastery: (5)
As of 2024-04-24 07:40 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found