I have a problem for which I already have a solution, but I can't stop feeling that it can be solved much more elegant an perhaps more efficient as well.
I implemented search in IRC-Logs, and I want to return not only matching lines, but a few lines of context as well. Of course I don't want to display lines twice, and I want to hilight the lines that really match.
This is how my code looks like:
my $max = 21; # In the "real world" I obtain these line IDs from a db query, and do # the next step (generate @padded_overlap) on the fly my @nums = (1, 5, 6, 8, 15, 20); my $pad = 1; # lines of context on each side my @padded_overlap = map { $_ - $pad .. $_ + $pad } @nums; # guard against context from next/previous day shift @padded_overlap while ($padded_overlap[0] < 0); pop @padded_overlap while ($padded_overlap[-1] > $max); # remove duplicates my $prev = shift @padded_overlap; my @padded = ($prev); for (@padded_overlap) { if ($_ > $prev){ push @padded, $_; $prev = $_; } } # print the lines for (@padded){ if (@nums && $_ == $nums[0]){ print "Hilighted: $_\n"; shift @nums; } else { print "$_\n"; } }
$max is the index of the last line on the day that is displayed, thus in the first two loops only 2*$pad lines are removed at most.
What I hate particularly is that I iterate three times over the list(s). How can I decrease that?
In reply to Padding search results with context by moritz
For: | Use: | ||
& | & | ||
< | < | ||
> | > | ||
[ | [ | ||
] | ] |