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]} } ; 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__ ...