Getting equivalent elements in a range/array

Ali Çehreli acehreli at yahoo.com
Sat May 7 23:09:19 PDT 2011


On 05/07/2011 09:07 PM, Andrej M. wrote:
> I want to turn this:
> auto arr = [1, 1, 2, 3, 4, 4];
>
> into this:
> auto arr2 = [[1, 1], [2], [3], [4, 4]];
>
> I want an array of arrays of the same elements. Lazy or not, I don't care.
>
> I thought I could get away with this inside some while loop:
> auto equals = array(filter!"a == b"(arr));
> arr = arr[equals.length-1..$];
>
> Nope.
>
> I need this for some buffered output, where the requirement is the elements of the buffer all need to have the same properties so a function can output a buffer of elements in one call instead of calling the function for each element (the function call is expensive).

This seems to work, but needs more work. :)

import std.stdio;
import std.array;

struct EquivalentElements
{
     int[] range;
     int[] front_;

     this(int[] range)
     {
         this.range = range;
         this.front_ = popEqualFront(this.range);
     }

     bool empty()
     {
         return front_.empty;
     }

     int[] front()
     {
         return front_;
     }

     void popFront()
     {
         this.front_ = popEqualFront(this.range);
     }

     private int[] popEqualFront(ref int[] range)
     {
         int[] front;

         if (!range.empty) {
             do {
                 front ~= range[0];
                 range = range[1..$];

             } while (!range.empty &&
                      (front[$-1] == range[0]));
         }

         return front;
     }
}

void main()
{
     writeln(EquivalentElements([1, 1, 2, 3, 4, 4]));
}


More information about the Digitalmars-d-learn mailing list