Thread overview
What to use instead of array.join if RHS is not a range?
Nov 27, 2012
Andrej Mitrovic
Nov 27, 2012
bearophile
Nov 27, 2012
bearophile
November 27, 2012
This is what I want:

struct S { int x; }

void main()
{
    S[] arr = [S(2), S(4), S(6)];
    S s = S(0);
    arr.join(s);  // fails here
    assert(arr == [S(2), S(0), S(4), S(0), S(6)]);
}

Calling join like that fails, specifically it fails because "s" is not a forward range (I don't know why it's implemented like that..). Is there some other function which can join with an element as a separator?
November 27, 2012
Andrej Mitrovic:

> Is there some other function which can join with an
> element as a separator?

This is not efficient, but it's useful to call it inside the post-condition of a more efficient version to test the results of the faster version:


import std.stdio, std.array;

// http://hackage.haskell.org/packages/archive/base/latest/doc/html/src/Data-List.html#intersperse
T[] intersperse(T)(T[] items, T sep) pure nothrow {
    static T[] prependToAll(T[] items, T sep) pure nothrow {
        return items.empty ?
               [] :
               sep ~ (items.front ~ prependToAll(items[1 .. $], sep));
    }

    return items.empty ?
           [] :
           items.front ~ prependToAll(items[1 .. $], sep);
}

void main() {
   static struct S { int x; }
   auto arr = [S(2), S(4), S(6)];
   auto s = S(10);
   auto result = arr.intersperse(s);
   writeln(result);
}


Bye,
bearophile
November 27, 2012
> sep ~ (items.front ~ prependToAll(items[1 .. $], sep));

Better:

[sep, items.front] ~ prependToAll(items[1 .. $], sep);

Bye,
bearophile