|
Prev: Compiling Perl modules on AIX using gcc instead of cc_r?
Next: beginner question on using the Win32::OLE module
From: Pietro on 11 Aug 2005 17:38 Hallo, I made a little script that sort the lines of a file: #! /usr/bin/perl sub numerically {$a <=> $b;} @array = <>; @array = sort numerically (@array); print (@array); Maybe the code is not so good, but why if I give thi input file: 1.3.5.6 1.1.2.4 111.222.444.555 1.2.5.6 11.22.44.55 1.2.3.4 11.23.66.77 11.22.33.44 111.222.333.444 11.22.44.55 111.223.333.444 11.22.33.44 1.2.3.4 11.22.22.22 11.22.55.66 1.2.4.5 111.222.555.666 1.1.2.3 1.3.4.5 The result is this: 1.1.2.4 1.1.2.3 1.2.5.6 1.2.3.4 1.2.3.4 1.2.4.5 1.3.5.6 1.3.4.5 11.22.44.55 11.22.33.44 11.22.44.55 11.22.33.44 11.22.22.22 11.22.55.66 11.23.66.77 111.222.444.555 111.222.333.444 111.222.555.666 111.223.333.444 As I see perl sots only the first two field delimited by a ".", the others are inserted as a fifo, first line encountered first line wrote in output, why doesn't perl compare all the line? Thanks, Pietro. -- I will build myself a copper tower With four ways out and no way in But mine the glory, mine the power (So I chose AmigaOS and GNU/Linux)
From: Stephen Hildrey on 11 Aug 2005 18:43 Pietro wrote: > As I see perl sots only the first two field delimited by a ".", the others > are inserted as a fifo, first line encountered first line wrote in output, > why doesn't perl compare all the line? You're using a *numeric* sort. "1.3.5.6" etc are not numbers. If you had "use warnings;", you would see a load of these: Argument "1.1.2.4\n" isn't numeric in numeric comparison (<=>) Steve
From: Brian McCauley on 11 Aug 2005 17:51 Pietro wrote: > sub numerically {$a <=> $b;} > > Maybe the code is not so good, but why if I give thi input file: > > 1.3.5.6 > 1.1.2.4 > 111.222.444.555 > As I see perl sots only the first two field delimited by a ".", the others > are inserted as a fifo, first line encountered first line wrote in output, No, Perl sort the strings as numbers. If you convert the string '1.3.5.6' to a number then you get the number 1.3 (and you'll get a warning too if you've enabled warnings. Sounds to me like you may want to compare the strings as IP address. There are modules on CPAN to manipulate IP addresses.
From: J?rgen Exner on 11 Aug 2005 18:47 Pietro wrote: > Hallo, I made a little script that sort the lines of a file: > > #! /usr/bin/perl > sub numerically {$a <=> $b;} > @array = <>; > @array = sort numerically (@array); > print (@array); > > Maybe the code is not so good, but why if I give thi input file: > > 1.3.5.6 > 1.1.2.4 [...] > 111.222.555.666 > 1.1.2.3 > 1.3.4.5 > > The result is this: > > 1.1.2.4 > 1.1.2.3 > 1.2.5.6 [...] > 111.222.444.555 > 111.222.333.444 > 111.222.555.666 > 111.223.333.444 > > As I see perl sots only the first two field delimited by a ".", Well, no. Perl is sorting _numerically_, just as you asked it to do. And the numerical value of e.g. the string 1.3.4.5 happens to be 1.3. > the > others are inserted as a fifo, first line encountered first line > wrote in output, Yep, that's a great feature. It is called a 'stable sort'. If two items have the same sort value, e.g. 111.222.444.555 and 111.222.333.444 which both have the value of 111.222, then since version 5.8 perl ensures that their relative position is not changed. Comes in very handy if you have to sort by multiple keys, e.g. first by first name, then by last name. > why doesn't perl compare all the line? But perl does compare all the line. Or rather the numerical value of the line just as you told it to do. jue
From: William James on 11 Aug 2005 20:46
Pietro wrote: > Maybe the code is not so good, but why if I give thi input file: > > 1.3.5.6 > 1.1.2.4 > 111.222.444.555 > 1.2.5.6 > 11.22.44.55 > 1.2.3.4 > 11.23.66.77 > 11.22.33.44 > 111.222.333.444 > 11.22.44.55 > 111.223.333.444 > 11.22.33.44 > 1.2.3.4 > 11.22.22.22 > 11.22.55.66 > 1.2.4.5 > 111.222.555.666 > 1.1.2.3 > 1.3.4.5 > > The result is this: > > 1.1.2.4 > 1.1.2.3 > 1.2.5.6 > 1.2.3.4 > 1.2.3.4 > 1.2.4.5 > 1.3.5.6 > 1.3.4.5 > 11.22.44.55 > 11.22.33.44 > 11.22.44.55 > 11.22.33.44 > 11.22.22.22 > 11.22.55.66 > 11.23.66.77 > 111.222.444.555 > 111.222.333.444 > 111.222.555.666 > 111.223.333.444 > > As I see perl sots only the first two field delimited by a ".", the others > are inserted as a fifo, first line encountered first line wrote in output, > why doesn't perl compare all the line? Pietro, I think it would be easier using Ruby. ----- program starts here ----- puts DATA.read.sort_by{ |x| x.split('.').map{|s| s.to_i} } __END__ 1.3.5.6 1.1.2.4 111.222.444.555 1.2.5.6 11.22.44.55 1.2.3.4 11.23.66.77 11.22.33.44 111.222.333.444 11.22.44.55 111.223.333.444 11.22.33.44 1.2.3.4 11.22.22.22 11.22.55.66 1.2.4.5 111.222.555.666 1.1.2.3 2.3.4.5 ----- program ends here ----- The output is: 1.1.2.3 1.1.2.4 1.2.3.4 1.2.3.4 1.2.4.5 1.2.5.6 1.3.5.6 2.3.4.5 11.22.22.22 11.22.33.44 11.22.33.44 11.22.44.55 11.22.44.55 11.22.55.66 11.23.66.77 111.222.333.444 111.222.444.555 111.222.555.666 111.223.333.444 |