Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Re: most efficient buffer sort

by serf (Chaplain)
on Dec 14, 2005 at 12:15 UTC ( #516593=note: print w/ replies, xml ) Need Help??


in reply to most efficient buffer sort

I have been a bit naughty in assuming that it's OK to use

my ($first, $sort, $second, $tail) = split(/\s+/, $_);
to replace your:
m/^(\w+)\s+(\d+)\s+(\w+)(.*)$/
Because if you have multiple spaces immediately after $second they will be lost - but as you're putting the data into HTML table cells this shouldn't be an issue.

NB: I used split(/\s+/, $_) and not split(' ', $_) because you were matching /^(\w+), which may just have been for efficiency and anchoring, but I don't know that you didn't need to make sure that there was no leading white space on the line in the input file.

I have not used GrandFather's map because I needed to do quite a lot to the elements returned by the sort (the tests on $sort and the sprintf) and it looked like it was going to be messy and possibly difficult trying to fit it all in there.

I like map, but I tend to shy away from using it for more than the most basic usage - I know 95%+ of the people I've ever worked with who have to deal with Perl would not be able to understand how the map worked, but could all unroll a foreach loop if they needed to change the code after I had moved on to my next contract.

use strict; use warnings; my $buffer; my $input = "input.dat"; my %colour = ( 'lt_90' => '#00FF00', 'lt_180' => '#FF6600', 'gt_179' => '#FF0000' ); my @lines; open( INPF, $input ) or die "Can't read '$input': $!\n"; while (<INPF>) { my ($first, $sort, $second, $tail) = split(/\s+/, $_); if ( defined $tail && $sort =~ /^\d+$/ ) { push(@lines, [$first, $sort, $second, $tail]); } else { # die "Unable to match any lines: $!\n"; # Do you really want to die with $! here? # There wasn't an error, just a failed test, # so $! won't have a relevant message in it. # (I get "Bad file descriptor" YMMV on your OS?) # Perhaps you want something like: chomp(); die "line: '$_' does not match input format\n"; } } close (INPF); for my $line ( sort { $a->[1] <=> $b->[1] } @lines ) { my ($first, $sort, $second, $tail) = @{$line}; my $colour = "gt_179"; if ( $sort < 90 ) { $colour = "lt_90"; } elsif ( $sort < 180 ) { $colour = "lt_180"; } $buffer .= sprintf ( "<tr bgcolor='%s'><td>%s</td><td>%s</td><td>%s</td><td>%s</td> +</tr>\n", $colour{$colour}, $first, $sort, $second, $tail); } print "$buffer";


Comment on Re: most efficient buffer sort
Select or Download Code
Re^2: most efficient buffer sort
by Anonymous Monk on Dec 14, 2005 at 12:36 UTC
    Good point re the die statement. It's just habit to put that line in. I've changed it accordingly. Thanks.
Re^2: most efficient buffer sort
by salva (Abbot) on Dec 14, 2005 at 13:06 UTC
    I like map...

    calling die from inside a map block is not a very good idea, it can hit a bug on the perl interpreter that has only recently being corrected:

    for (1) { map { die } 2 }

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://516593]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (8)
As of 2015-07-07 11:21 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (88 votes), past polls