View source code
Display the source code in std/algorithm/iteration.d from which this page was generated on github.
Report a bug
If you spot a problem with this page, click here to create a Bugzilla issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using local clone.

Function std.algorithm.iteration.joiner

Lazily joins a range of ranges with a separator. The separator itself is a range. If a separator is not provided, then the ranges are joined directly without anything in between them (often called flatten in other languages).

auto auto joiner(RoR, Separator) (
  RoR r,
  Separator sep
)
if (isInputRange!RoR && isInputRange!(ElementType!RoR) && isForwardRange!Separator && is(ElementType!Separator : ElementType!(ElementType!RoR)));

auto auto joiner(RoR) (
  RoR r
)
if (isInputRange!RoR && isInputRange!(ElementType!RoR));

Parameters

NameDescription
r An input range of input ranges to be joined.
sep A forward range of element(s) to serve as separators in the joined range.

Returns

A range of elements in the joined range. This will be a forward range if both outer and inner ranges of RoR are forward ranges; otherwise it will be only an input range. The range bidirectionality is propagated if no separator is specified.

See also

std.range.chain, which chains a sequence of ranges with compatible elements into a single range.

Example

import std.algorithm.comparison : equal;
import std.conv : text;

assert(["abc", "def"].joiner.equal("abcdef"));
assert(["Mary", "has", "a", "little", "lamb"]
    .joiner("...")
    .equal("Mary...has...a...little...lamb"));
assert(["", "abc"].joiner("xyz").equal("xyzabc"));
assert([""].joiner("xyz").equal(""));
assert(["", ""].joiner("xyz").equal("xyz"));

Example

import std.algorithm.comparison : equal;
import std.range : repeat;

assert([""].joiner.equal(""));
assert(["", ""].joiner.equal(""));
assert(["", "abc"].joiner.equal("abc"));
assert(["abc", ""].joiner.equal("abc"));
assert(["abc", "def"].joiner.equal("abcdef"));
assert(["Mary", "has", "a", "little", "lamb"].joiner.equal("Maryhasalittlelamb"));
assert("abc".repeat(3).joiner.equal("abcabcabc"));

Example

joiner allows in-place mutation!

import std.algorithm.comparison : equal;
auto a = [ [1, 2, 3], [42, 43] ];
auto j = joiner(a);
j.front = 44;
writeln(a); // [[44, 2, 3], [42, 43]]
assert(equal(j, [44, 2, 3, 42, 43]));

Example

insert characters fully lazily into a string

import std.algorithm.comparison : equal;
import std.range : chain, cycle, iota, only, retro, take, zip;
import std.format : format;

static immutable number = "12345678";
static immutable delimiter = ",";
auto formatted = number.retro
    .zip(3.iota.cycle.take(number.length))
    .map!(z => chain(z[0].only, z[1] == 2 ? delimiter : null))
    .joiner
    .retro;
static immutable expected = "12,345,678";
assert(formatted.equal(expected));

Example

joiner can be bidirectional

import std.algorithm.comparison : equal;
import std.range : retro;

auto a = [[1, 2, 3], [4, 5]];
auto j = a.joiner;
j.back = 44;
writeln(a); // [[1, 2, 3], [4, 44]]
assert(equal(j.retro, [44, 4, 3, 2, 1]));

Authors

Andrei Alexandrescu

License

Boost License 1.0.