Reducing an array

monarch_dodra via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat Apr 19 10:27:10 PDT 2014


On Friday, 18 April 2014 at 22:11:17 UTC, bearophile wrote:
> This preserves ordering and it's in-place. Not tested much:
>
> void main() {
>     import std.stdio, std.traits;
>
>     auto data = [2, 1, 1, 3, 2, 3];
>
>     bool[ForeachType!(typeof(data))] seen;
>     size_t pos = 0;
>     foreach (immutable i; 0 .. data.length)
>         if (data[i] !in seen) {
>             if (pos != i)
>                 data[pos] = data[i];
>             seen[data[i]] = true;
>             pos++;
>         }
>     data.length = pos;
>
>     data.writeln;
> }
>
>
> Bye,
> bearophile

If you replace that "=" with a swap, then you can also preserve 
the duplicate elements at the end (although in no specific 
ordering):

import std.stdio : writefln;
import std.algorithm : canFind, swap;

//----
void main()
{
	auto arr = [1,1,5,2,3,2,2,4,5,5,1];
	size_t pos = 0;
	foreach(ref e; arr)
		if (!arr[0 .. pos].canFind(e))
			swap(arr[pos++], e);
	writefln("uniques: %s", arr[0 .. pos]);
	writefln("dupes:   %s", arr[pos .. $]);
}
//----

I was trying a "100% inplace" solution, but I found nothing 
better than N². It's  basically still what you submitted though.


More information about the Digitalmars-d-learn mailing list