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]