Well, it can be made a little more compact. The following doesn't bother validating data, although such validation is fairly trivial:
use strict; use warnings; my @res = analyze (); print "$_->{f1},$_->{f2},$_->{f3}\n" for @res; sub analyze { # get the data as an array of hashes just like DBI would return my @data = map { chomp; my @f = split /,/; {f1 => $f[0], f2 => $f[1], f3 => $f[2]} } <DATA>; my %lists; # Build coloured lists push @{$lists{$data[$_]{f2}}}, $_ for 0 .. $#data; # Find the spans my $redIndex = $lists{Red}[0]; my @priorWhites = grep {$_ < $redIndex} @{$lists{White}}; my $firstWhite = $priorWhites[-4]; my @priorBlues = grep {$_ < $firstWhite} @{$lists{Blue}}; my @postWhites = grep {$_ > $redIndex} @{$lists{White}}; my $lastWhite = $postWhites[3]; my @postBlues = grep {$_ > $lastWhite} @{$lists{Blue}}; # Build the output list my @indexes = ($priorBlues[-1], @priorWhites[-4 .. -1], $redIndex, @postWhites[0 .. 3], $postBlues[0]); return @data[@indexes]; } __DATA__ ...
generates output per OP's sample given OP's data.
In reply to Re: Extracting array elements on either side of a match
by GrandFather
in thread Extracting array elements on either side of a match
by punkish
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |