On Tue, 21 May 2013 18:00:07 -0400, bearophile <bearophileh...@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

Reply via email to