Aack!  My email client (mail.yahoo.com) has substituted all for the 'backslash' n's 
with literal
newlines, thus making my code virtually unreadable.  I hope this hasn't happened to 
anyone else,
or what you read below may be very confusing.

--- Curtis Poe <[EMAIL PROTECTED]> wrote:
> --- Roy Peters <[EMAIL PROTECTED]> wrote:
> > hi,
> > 
> > I have the following string 
> > 
> > $a = 
> > "buy 10/23/01 100 12.625 50 25.25 
> 
> >  buy 10/25/01 100 12.625 50 25.25 
> 
> >  buy 09/1/01 100 12.625 50 25.25 
> 
> >  buy 1/23/01 100 12.625 50 25.25 
> ";
> > 
> > I would like to sort this by the date (ie the second field) in the
> > above string. 
> > 
> > So it looks like this:
> > 
> > $a = 
> > "buy 1/23/01 100 12.625 50 25.25 
> ";
> >  buy 09/1/01 100 12.625 50 25.25 
> 
> >  buy 10/23/01 100 12.625 50 25.25 
> 
> >  buy 10/25/01 100 12.625 50 25.25 
> ;
> > 
> > What's the cleanest way to do this?
> 
> Roy,
> 
> You need to be *extremely* specific about how your input and output should look.  
>Your input,
> for
> example, has a 
>  followed by a newline.  That interpolates as two newlines between each record.  
>Further, all
> records after the first have a space before the word 'buy'.  Is this truly 
>reflecting your data?
> 
> Your output is also not valid Perl.  I'll show you what I came up with, but it's 
>going to be
> difficult to maintain if you're not familiar with map and sort.
> 
> ##########################################
> use strict;
> use Data::Dumper;
> 
> my $data = "buy 1/23/01 100 12.625 50 25.25 
> 
>  buy 09/1/01 100 12.625 50 25.25 
> 
>  buy 10/23/01 100 12.625 50 25.25 
> 
>  buy 10/25/01 100 12.625 50 25.25 
> ";
> 
> my @data = split /
> 
> /, $data;
> 
> @data = map  { join ' ', ( $_->[0], ( join '/', @{$_->[1]} ), $_->[2] ) }
>               sort { $a->[1][2] <=> $b->[1][2] || $a->[1][0] <=> $b->[1][0] || 
>$a->[1][1] <=> $b->[1][1] }
>               map  { [ $_->[0], [split ///, $_->[1]], $_->[2] ] }
>               map  { [split( /s+/, trim( $_ ), 3) ] } @data;
> print Dumper @data;
> 
> sub trim {
>       my $data = shift;
>       $data =~ s/^s+//;
>       $data =~ s/s+$//;
>       return $data;
> }
> ##########################################
> 
> I was going to clean that up and document it, but then I realized that since I was 
>unsure as to
> whether or not my understanding of your input was accurate, I could be spending a 
>lot of time
> explaining something that doesn't fit what you need.  Regardless, here's a brief 
>explanation:
> 
> I split the data on two newlines (since this is what you have).
> 
> The first map in the Schwartzian transform (read them bottom to top) splits the data 
>on spaces
> (after trimming out extraneous beginning and closing whitespace) and uses splits 
>optional 3rd
> parameter to limit the split to three scalars:
> 
> This:
>     ' buy 10/25/01 100 12.625 50 25.25 '
> Becomes:
>     'buy', '10/25/01', '100 12.625 50 25.25'
> 
> The next map splits the second element (the date) on the forward slash and creates 
>an array ref
> for that element.
> 
> The sort sorts on the year, then the month, then the day.
> 
> The last map then puts the string back together.  Note that the beginning and ending 
>whitespace
> is
> lost.  If that's important, you'll need to modify this solution.
> 
> I realize that this is probably very confusing if you haven't used this before, so I 
>offer my
> apologies.  If you have show us your *exact* input data and the code that reads it, 
>we can
> probably offer an easier to follow solution.
> 
> Cheers,
> Curtis "Ovid" Poe
> 
> =====
> Senior Programmer
> Onsite! Technology (http://www.onsitetech.com/)
> "Ovid" on http://www.perlmonks.org/


__________________________________________________
Do You Yahoo!?
Make a great connection at Yahoo! Personals.
http://personals.yahoo.com

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to