Remove duplicates

Steven Schveighoffer schveiguy at yahoo.com
Tue May 21 16:49:50 PDT 2013


On Tue, 21 May 2013 18:00:07 -0400, bearophile <bearophileHUGS at lycos.com>  
wrote:

> Sometimes I have need a simple function like this, related to  
> std.string.squeeze:
>
>
> // Must keep the original order of the items.
> // Slow implementation that shows the semantics.
> T[] noDupes(T)(in T[] s) {
>      import std.algorithm: canFind;
>      T[] result;
>      foreach (T c; s)
>          if (!result.canFind(c))
>              result ~= c;
>      return result;
> }
>
> void main() {
>      import std.string: squeeze;
>      assert("AAAA".noDupes == "A");
>      assert("AAAA".squeeze == "A");
>      assert("ABAC".noDupes == "ABC");
>      assert("ABAC".squeeze == "ABAC");
> }
>
>
> Do you know if this function (or a simple way to implement it) already  
> in Phobos?

This seems to work for ASCII strings, but the conversion to array is  
required (I think because writeln may re-evaluate the range's front more  
than once):

Should be O(n), but doesn't really get around the memory allocation.  You  
could probably write a custom range that does this properly (doesn't set  
present until popFront is called):

import std.algorithm;
import std.array;
import std.stdio;

void main()
{
     bool present[256];
     // writes "ABC"
     writeln(array("ABAC".filter!((a){scope(exit) present[a] = true; return  
!present[a];})));
}

Kind of a violation of how a range should work, front should be the same  
across multiple calls!  But it does the trick :)

-Steve


More information about the Digitalmars-d-learn mailing list