An input range of input ranges to be joined.
A forward range of element(s) to serve as separators in the joined range.
A range of elements in the joined range. This will be a bidirectional range if both outer and inner ranges of RoR are at least bidirectional ranges. Else if both outer and inner ranges of RoR are forward ranges, the returned range will be likewise. Otherwise it will be only an input range. The range bidirectionality is propagated if no separator is specified.
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"));
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"));
joiner allows in-place mutation!
import std.algorithm.comparison : equal; auto a = [ [1, 2, 3], [42, 43] ]; auto j = joiner(a); j.front = 44; assert(a == [ [44, 2, 3], [42, 43] ]); assert(equal(j, [44, 2, 3, 42, 43]));
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));
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; assert(a == [[1, 2, 3], [4, 44]]); assert(equal(j.retro, [44, 4, 3, 2, 1]));
std.range.chain, which chains a sequence of ranges with compatible elements into a single range.
Note: When both outer and inner ranges of RoR are bidirectional and the joiner is iterated from the back to the front, the separator will still be consumed from front to back, even if it is a bidirectional range too.
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).