First method, an old fashioned loop within a loop.
my @list = qw(AGCT AGGT GG AGCT);
MAIN: for my $i (0..$#list) {
my $substr_re = qr/$list[$i]/;
for my $j (0..$#list) {
next if $i == $j || ! defined $list[$j];
if ($list[$j] =~ $substr_re) {
undef $list[$i];
next MAIN;
}
}
}
my @unique = grep {defined} @list;
print "$_\n" for @unique;
Update: Increase efficiency by grouping the strings by size before processing:
use strict;
use warnings;
my @list = qw(AGCT AGGT GG AGCT);
my %bucket;
for (@list) {
push @{$bucket{length($_)}}, $_;
}
# Only want to sort these once.
my @sizes = sort {$a <=> $b} keys %bucket;
while (my $size = shift @sizes) {
MAIN: for my $i (0..$#{$bucket{$size}}) {
# Same Size first
for my $j ($i+1..$#{$bucket{$size}}) {
if ($bucket{$size}[$i] eq $bucket{$size}[$j]) {
undef $bucket{$size}[$i];
next MAIN;
}
}
# Bigger strings
my $substr_re = qr/$bucket{$size}[$i]/;
for my $bigger (@sizes) {
for my $str (@{$bucket{$bigger}}) {
if ($str =~ $substr_re) {
undef $bucket{$size}[$i];
next MAIN;
}
}
}
}
}
my @unique = grep {defined} map {@$_} values %bucket;
print "$_\n" for @unique;