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

hi all

I have a plain text file with a couple of hundred lines in it like so:

001 client 1
002 client 2
003 client 3
etc etc

My problem is that I need to loop through this file and print out the clients in alphabetical order - the thing is that each client must retain its order number, the reason being is that each client is a link, and pressing on this link prints out the client and its number to 2 input text boxes. Printing them out is no problem (using javascript) but I cant get perl to sort the client alphabetically while keeping the correct number.

I've written 2 subs - the first works fine as its the numbers that are printed but the second one has stumped me - I tried to use arrays, hashes etc but no joy

#this one works sub getNumbers{ foreach(@file){ next if m/(^#|^$)/; my ($cltnbr, $cltname) = split (' ', $_); print "<span class='spacer'><a href='#' title='$cltnbr' name=' +$cltname' onclick='fillText(this);'>$cltnbr</a></span>"; } }


#help! sub getClients{ foreach(@file){ next if m/(^#|^$)/; my ($cltnbr, $cltname) = split (' ', $_); print "<a href='#' title='$cltnbr' name='$cltname' onclick='fi +llText(this);'>$cltname</a><br />"; } }


any help appreciated!

Mike

Replies are listed 'Best First'.
Re: sorting a file
by Roy Johnson (Monsignor) on Oct 18, 2005 at 16:42 UTC
    sub getClients{ my @tuples = map [split ' ', $_] grep { !/^(?:#|$)/ } @file; foreach(sort {$a->[1] cmp $b->[1]} @tuples){ my ($cltnbr, $cltname) = @$_; print "<a href='#' title='$cltnbr' name='$cltname' onclick='fi +llText(this);'>$cltname</a><br />"; } }

    Caution: Contents may have been coded under pressure.
Re: sorting a file
by InfiniteSilence (Curate) on Oct 18, 2005 at 17:50 UTC
    This is Roy Johnson's code, but changed a bit:

    #!/usr/bin/perl -w use strict; my @file; while(<DATA>){ chomp; push @file,$_; } &getClients; #---------------------- sub getClients{ my @tuples = map {[split /\s+/, $_]} grep { !/^(?:#|$)/ } @file; foreach(sort {$a->[1] cmp $b->[1]} @tuples){ my ($cltnbr, $cltname, $clNum) = @$_; print "<a href='#' title='$cltnbr' name='$cltname $clNum' oncl +ick='fillText(this);'>$cltname $clNum</a><br />"; print qq|\n|; } } 1; __DATA__ 001 client 1 002 client 2 003 client 3

    Which produces:

    <a href='#' title='001' name='client 1' onclick='fillText(this);'>clie +nt 1</a><br /> <a href='#' title='002' name='client 2' onclick='fillText(this);'>clie +nt 2</a><br /> <a href='#' title='003' name='client 3' onclick='fillText(this);'>clie +nt 3</a><br />

    Now, instead of using a global variable like the above you should pass it into the routine as a reference.

    Celebrate Intellectual Diversity

      many thanks for your help - I couldnt get your code to work, but got round it a different, less sophisticated way. Will study map and grep tho

      i used

      sub getClients{ my @sortedclients; my @joinedarray; foreach(@clients){ next if m/(^#|^$)/; my ($cltnbr, $cltname) = split (' ', $_); my $joined = join " ", $cltname, $cltnbr; push @joinedarray, $joined; } foreach(@sortedclients = sort @joinedarray){ my ($cltname, $cltnbr) = split (' ', $_); print "<a href='#' title='$cltnbr' name='$cltname' onclick='fi +llText(this);'>$cltname</a><br />"; } }