in reply to Unique List of Common Characters Between Two Strings

Here's some trickery with the oft-forgotten index.

sub in_common { my $all = join '', scalar( reverse $_[ 0 ] ), @_[ 1 .. $#_ ]; my $offs = length $_[ 0 ]; my $minpos = 0; return grep { my $pos = index( $all, $_, $offs-- ); $pos >= $minpos++; } split //, $_[ 0 ]; }

The trick is to fold checking for non-existant characters and already-checked-for characters into a single condition: index returns -1 if it doesn't find the character and a 0-based offset if it does. Therefore in the first iteration, the check is for >= 0. This seen character is then included in the searched string. On the next iteration, the check is for offset >= 1 — ie it must exist in the string (offset > -1) but not be the character already seen (offset >= 1). In the next iteration, the offset must be >= 2 to account for already seen characters.

In C, this approach would beat all others for speed and would be the most straightforward one too. But in Perl, it is harder to read than the others and slower than most too. sleepingsquirrel's regex is probably the fastest because it doesn't loop explicitly in Perl; merlyn's variation of your own solution is the clearest.

Makeshifts last the longest.