Cosmos has asked for the wisdom of the Perl Monks concerning the following question:

Hello y'all I am reading from a file like this:
foreach $line (@FILE) { ($id_number, $title, $date) = split(/\|/,$line);
I need to print the results sorted alphabetically by the title. Can it be done? How.


________________

Cosmos,
MonoPro.com

Replies are listed 'Best First'.
Re: Is this sort of possible
by grep (Monsignor) on Dec 31, 2001 at 13:46 UTC
    What you can use is the Schwartzian Transform (thx merlyn). Here is my attempt at your problem.
    #!/usr/bin/perl -w use strict; my @FILE = ('123|title|1/1/01','123|btitle|1/1/01','123|atitle|1/1/01' +); print @FILE,"\n"; my @output = map { $_->[0] } sort { $a->[1] cmp $b->[1] } map { [$_, (split(/\|/,$_))[1]] } @FILE; print @output,"\n";

    grep
    grep> cd pub grep> more beer
      Or why even bother reading the file contents into an array?

      #!/usr/bin/perl -wd open( FILE, "file.dat" ) || die "Cannot Open file ($!)\n"; my @output = map { $_->[0] } sort { $a->[1] cmp $b->[1] } map { [$_, (split(/\|/,$_))[1]] } <FILE>; close( FILE ); print @output, "\n";

      -derby

(Ovid) Re: Is this sort of possible
by Ovid (Cardinal) on Dec 31, 2001 at 13:50 UTC

    Untested.

    my @data; foreach (<FILE>) { push @data, [split( /\|/, $_, 3 ) ]; } @data = sort { $a->[1] cmp $b->[1] } @data; foreach ( @data ) { my ( $id_number, $title, $date ) = @$_; print "ID: $id_numer\tTitle: $title\tDate: $date\n"; }

    Cheers,
    Ovid

    Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

Re: Is this sort of possible
by AidanLee (Chaplain) on Dec 31, 2001 at 18:57 UTC
    While grep's and Ovid's examples are great, I thought you might like something a bit more self-documenting:
    my @Data = (); while my $line (<FILE>) { push @Data, {}; @{$Data[-1]}{ 'ID', 'Title', 'Date' } = split( /\|/, $line ); } @Data = sort { $a->{'Title'} cmp $b->{'Title'} } @Data; foreach my $line ( @Data ) { print join( ' | ', @$line{ 'ID', 'Title', 'Date' } ), "\n"; }
Re: Is this sort of possible
by jryan (Vicar) on Dec 31, 2001 at 23:21 UTC

    If you don't want to use the transform, you can always sort multiple arrays by the order of one:

    my @ids; my @titles; my @dates; foreach $line (@FILE) { my($id_number, $title, $date) = split(/\|/,$line); push (@ids, $id_number); push (@titles, $title); push (@dates, $date); } my @sorted = sort { $titles[$a] cmp $titles[$b] } (0 .. $#titles); @ids = @ids[@sorted]; @titles = @titles[@sorted]; @dates = @dates[@sorted];

    Not quite as elegant looking as the Schwartzian Transform, but it will do the trick. Also, this will be easier to work with if you need to modify $title, $id_number, or $date in the foreach loop.

      Thank you all.