Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Numerically sort a file on a given column where column is a $var

Reply
Thread Tools

Numerically sort a file on a given column where column is a $var

 
 
joemacbusiness@yahoo.com
Guest
Posts: n/a
 
      07-17-2008
Hi All,

I want a subroutine that will sort a file on any given column.
So I have a file like this:

300 400 500 600 700
33 2337483 482 78374 4567
10 20 30 40 50
1000 1001 1002 1003 1004
9 8 7 6 5

And I run my numericSortCol() routine on it sorting on
column 1 and should get this:

9 8 7 6 5
10 20 30 40 50
300 400 500 600 700
1000 1001 1002 1003 1004
33 2337483 482 78374 4567

The problem is that I cannot get the bynum() to accept 2 args.
The code will work if I hard-code the $col in bynum, and
tweek the "problem line" a bit but that defeats the purpose of the
"sort on column" feature.

Does anyone have a solution for this?

Thanks, --Joe M.

######################### Here's the code I have so far:
[joe@localhost work]$ cat test18.pl
#!/usr/bin/perl

my $infile = "test18.in";
open(F,"$infile") || print "cannot open $infile $!";
my @array = <F>;
close(F);

numericSortCol(1,\@array);

sub numericSortCol {
my $col = shift;
my $aref = shift;
foreach my $item (sort bynum($col,@{ $aref })){ # <<<< problem
line??
print "item: $item\n";
}
}

sub bynum {
my $col = shift;
@a = split(/\s+/,$a);
@b = split(/\s+/,$b);
$a[$col] <=> $b[$col];
# $a[1] <=> $b[1];
}
[joe@localhost work]$
[joe@localhost work]$
######################### Here's the input file
[joe@localhost work]$ cat test18.in
300 400 500 600 700
33 2337483 482 78374 4567
10 20 30 40 50
1000 1001 1002 1003 1004
9 8 7 6 5
[joe@localhost work]$
[joe@localhost work]$
######################### Here's the runtime:
[joe@localhost work]$ perl test18.pl
item: 1
item: 9 8 7 6 5

item: 10 20 30 40 50

item: 33 2337483 482 78374 4567

item: 300 400 500 600 700

item: 1000 1001 1002 1003 1004

[joe@localhost work]$

 
Reply With Quote
 
 
 
 
sln@netherlands.com
Guest
Posts: n/a
 
      07-17-2008
On Thu, 17 Jul 2008 14:29:52 -0700 (PDT), http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:

>Hi All,
>
>I want a subroutine that will sort a file on any given column.


Maybe your just in a rush, but I stopped reading here, when I read "sort a file"

sln
 
Reply With Quote
 
 
 
 
Uri Guttman
Guest
Posts: n/a
 
      07-18-2008
>>>>> "j" == joemacbusiness <(E-Mail Removed)> writes:

j> The problem is that I cannot get the bynum() to accept 2 args.
j> The code will work if I hard-code the $col in bynum, and
j> tweek the "problem line" a bit but that defeats the purpose of the
j> "sort on column" feature.

j> open(F,"$infile") || print "cannot open $infile $!";

useless use of quotes on a scalar. not needed and it can be a bug.

j> my @array = <F>;
j> close(F);

use File::Slurp ;
my @data = read_file( $infile ) ;

j> numericSortCol(1,\@array);

j> sub numericSortCol {
j> my $col = shift;
j> my $aref = shift;
j> foreach my $item (sort bynum($col,@{ $aref })){ # <<<< problem
j> line??

well, that isn't how perl's sort works. it can take a sub name (you have
a sub call) or a code block.


and you should look at Sort::Maker which can do this for you
easily. just create a simple expression to get the column you want based
on $_. that could be something like:

(split( ' ', $_))[$col]

the rest i leave as an exercise.

uri

--
Uri Guttman ------ (E-Mail Removed) -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Free Perl Training --- http://perlhunter.com/college.html ---------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
 
Reply With Quote
 
Jens Thoms Toerring
Guest
Posts: n/a
 
      07-18-2008
(E-Mail Removed) wrote:
> Hi All,


> I want a subroutine that will sort a file on any given column.
> So I have a file like this:


> 300 400 500 600 700
> 33 2337483 482 78374 4567
> 10 20 30 40 50
> 1000 1001 1002 1003 1004
> 9 8 7 6 5


> And I run my numericSortCol() routine on it sorting on
> column 1 and should get this:


> 9 8 7 6 5
> 10 20 30 40 50
> 300 400 500 600 700
> 1000 1001 1002 1003 1004
> 33 2337483 482 78374 4567


> The problem is that I cannot get the bynum() to accept 2 args.
> The code will work if I hard-code the $col in bynum, and
> tweek the "problem line" a bit but that defeats the purpose of the
> "sort on column" feature.


> ######################### Here's the code I have so far:
> [joe@localhost work]$ cat test18.pl
> #!/usr/bin/perl


> my $infile = "test18.in";
> open(F,"$infile") || print "cannot open $infile $!";
> my @array = <F>;
> close(F);


> numericSortCol(1,\@array);


> sub numericSortCol {
> my $col = shift;
> my $aref = shift;
> foreach my $item (sort bynum($col,@{ $aref })){ # <<<< problem
> line??


Look again at the documentation for the sort function. It takes
either a block or a function (that itself expects two arguments)
and, as the second argument, a list to be sorted. Your use of
sort doesn't seem to fit that very well and I guess if you had
used 'use warnings;' you would have been told so...

> print "item: $item\n";
> }
> }


> sub bynum {
> my $col = shift;
> @a = split(/\s+/,$a);
> @b = split(/\s+/,$b);
> $a[$col] <=> $b[$col];
> }


The simplest solution is probaly not to use a function name when
calling sort but instead a block like this:

#!/usr/bin/perl

use strict;
use warnings;

my @array = <DATA>;
numericSortCol( 1, \@array );

sub numericSortCol {
my ( $col, $aref ) = @_;

print "item: $_"
for sort { ( split /\s+/, $a )[ $col ] <=>
( split /\s+/, $b )[ $col ] } @$aref;
}

__DATA__
300 400 500 600 700
33 2337483 482 78374 4567
10 20 30 40 50
1000 1001 1002 1003 1004
9 8 7 6 5
Regards, Jens
--
\ Jens Thoms Toerring ___ (E-Mail Removed)
\__________________________ http://toerring.de
 
Reply With Quote
 
Ted Zlatanov
Guest
Posts: n/a
 
      07-18-2008
On Thu, 17 Jul 2008 14:29:52 -0700 (PDT) (E-Mail Removed) wrote:

j> I want a subroutine that will sort a file on any given column.
j> So I have a file like this:

j> 300 400 500 600 700
j> 33 2337483 482 78374 4567
j> 10 20 30 40 50
j> 1000 1001 1002 1003 1004
j> 9 8 7 6 5

j> And I run my numericSortCol() routine on it sorting on
j> column 1 and should get this:

j> 9 8 7 6 5
j> 10 20 30 40 50
j> 300 400 500 600 700
j> 1000 1001 1002 1003 1004
j> 33 2337483 482 78374 4567

Use the standard Unix utility `sort':

sort -n +1 FILE
(use "-k 1" instead of +1 if GNU sort is installed)

e.g. sort /etc/passwd by user ID:

sort -t: -n +2 /etc/passwd

Read the docs for `sort' for further information.

You can use Perl for this (as others have shown), but if all you want is
to sort a file by a simple key, `sort' will do just fine. It's also
likely to be much faster in most circumstances.

Ted
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
How to test a 'float' or 'double' zero numerically? Peng Yu C++ 14 09-15-2008 08:28 AM
Sort keys in a hash numerically mickey Perl Misc 5 08-11-2006 09:08 AM
program to numerically integrate rockwell C++ 7 09-25-2004 10:46 PM
Sorting alphabetically & numerically A.T. XML 3 07-29-2004 07:08 AM
Ado sort error-Ado Sort -Relate, Compute By, or Sort operations cannot be done on column(s) whose key length is unknown or exceeds 10 KB. Navin ASP General 1 09-09-2003 07:16 AM



Advertisments