std.algorithm.iteration.splitter
- multiple declarations
Function splitter
Lazily splits a range using an element or range as a separator. Separator ranges can be any narrow string type or sliceable range type.
auto auto splitter(alias pred, Range, Separator)
(
Range r,
Separator s
)
if (is(typeof(binaryFun!pred(r .front, s)) : bool) && (hasSlicing!Range && hasLength!Range || isNarrowString!Range));
auto auto splitter(alias pred, Range, Separator)
(
Range r,
Separator s
)
if (is(typeof(binaryFun!pred(r .front, s .front)) : bool) && (hasSlicing!Range || isNarrowString!Range) && isForwardRange!Separator && (hasLength!Separator || isNarrowString!Separator));
auto auto splitter(alias isTerminator, Range)
(
Range r
)
if (isForwardRange!Range && is(typeof(unaryFun!isTerminator(r .front))));
Two adjacent separators are considered to surround an empty element in
the split range. Use filter!(a => !a
on the result to compress
empty elements.
The predicate is passed to binaryFun
and accepts
any callable function that can be executed via pred(element, s)
.
Notes
If splitting a string on whitespace and token compression is desired,
consider using splitter
without specifying a separator.
If no separator is passed, the
predicate isTerminator
decides whether to accept an element of r
.
Parameters
Name | Description |
---|---|
pred | The predicate for comparing each element with the separator,
defaulting to "a == b" . |
r | The input range to be
split. Must support slicing and or be a narrow string type. |
s | The element (or range) to be treated as the separator between range segments to be split. |
isTerminator | The predicate for deciding where to split the range when no separator is passed |
Constraints
The predicate pred
needs to accept an element of r
and the
separator s
.
Returns
An input range of the subranges of elements between separators. If r
is a forward range
or bidirectional range,
the returned range will be likewise.
When a range is used a separator, bidirectionality isn't possible.
If an empty range is given, the result is an empty range. If a range with one separator is given, the result is a range with two empty elements.
See Also
splitter
for a version that splits using a regular
expression defined separator and
std
for a version that splits eagerly.
Example
Basic splitting with characters and numbers.
import std .algorithm .comparison : equal;
assert("a|bc|def" .splitter('|') .equal([ "a", "bc", "def" ]));
int[] a = [1, 0, 2, 3, 0, 4, 5, 6];
int[][] w = [ [1], [2, 3], [4, 5, 6] ];
assert(a .splitter(0) .equal(w));
Example
Adjacent separators.
import std .algorithm .comparison : equal;
assert("|ab|" .splitter('|') .equal([ "", "ab", "" ]));
assert("ab" .splitter('|') .equal([ "ab" ]));
assert("a|b||c" .splitter('|') .equal([ "a", "b", "", "c" ]));
assert("hello world" .splitter(' ') .equal([ "hello", "", "world" ]));
auto a = [ 1, 2, 0, 0, 3, 0, 4, 5, 0 ];
auto w = [ [1, 2], [], [3], [4, 5], [] ];
assert(a .splitter(0) .equal(w));
Example
Empty and separator-only ranges.
import std .algorithm .comparison : equal;
import std .range : empty;
assert("" .splitter('|') .empty);
assert("|" .splitter('|') .equal([ "", "" ]));
assert("||" .splitter('|') .equal([ "", "", "" ]));
Example
Use a range for splitting
import std .algorithm .comparison : equal;
assert("a=>bc=>def" .splitter("=>") .equal([ "a", "bc", "def" ]));
assert("a|b||c" .splitter("||") .equal([ "a|b", "c" ]));
assert("hello world" .splitter(" ") .equal([ "hello", "world" ]));
int[] a = [ 1, 2, 0, 0, 3, 0, 4, 5, 0 ];
int[][] w = [ [1, 2], [3, 0, 4, 5, 0] ];
assert(a .splitter([0, 0]) .equal(w));
a = [ 0, 0 ];
assert(a .splitter([0, 0]) .equal([ (int[]) .init, (int[]) .init ]));
a = [ 0, 0, 1 ];
assert(a .splitter([0, 0]) .equal([ [], [1] ]));
Example
Custom predicate functions.
import std .algorithm .comparison : equal;
import std .ascii : toLower;
assert("abXcdxef" .splitter!"a.toLower == b"('x') .equal(
[ "ab", "cd", "ef" ]));
auto w = [ [0], [1], [2] ];
assert(w .splitter!"a.front == b"(1) .equal([ [[0]], [[2]] ]));
Example
Use splitter without a separator
import std .algorithm .comparison : equal;
import std .range .primitives : front;
assert(equal(splitter!(a => a == '|')("a|bc|def"), [ "a", "bc", "def" ]));
assert(equal(splitter!(a => a == ' ')("hello world"), [ "hello", "", "world" ]));
int[] a = [ 1, 2, 0, 0, 3, 0, 4, 5, 0 ];
int[][] w = [ [1, 2], [], [3], [4, 5], [] ];
assert(equal(splitter!(a => a == 0)(a), w));
a = [ 0 ];
assert(equal(splitter!(a => a == 0)(a), [ (int[]) .init, (int[]) .init ]));
a = [ 0, 1 ];
assert(equal(splitter!(a => a == 0)(a), [ [], [1] ]));
w = [ [0], [1], [2] ];
assert(equal(splitter!(a => a .front == 1)(w), [ [[0]], [[2]] ]));
Example
Leading separators, trailing separators, or no separators.
import std .algorithm .comparison : equal;
assert("|ab|" .splitter('|') .equal([ "", "ab", "" ]));
assert("ab" .splitter('|') .equal([ "ab" ]));
Example
Splitter returns bidirectional ranges if the delimiter is a single element
import std .algorithm .comparison : equal;
import std .range : retro;
assert("a|bc|def" .splitter('|') .retro .equal([ "def", "bc", "a" ]));
Example
Splitting by word lazily
import std .ascii : isWhite;
import std .algorithm .comparison : equal;
import std .algorithm .iteration : splitter;
string str = "Hello World!";
assert(str .splitter!(isWhite) .equal(["Hello", "World!"]));
Function splitter
Lazily splits the string s
into words, using whitespace as the delimiter.
auto auto splitter(C)
(
C[] s
)
if (isSomeChar!C);
This function is string specific and, contrary to
splitter!(isWhite)
, runs of whitespace will be merged together
(no empty tokens will be produced).
Parameters
Name | Description |
---|---|
s | The string to be split. |
Returns
An input range of slices of the original string split by whitespace.
Example
import std .algorithm .comparison : equal;
auto a = " a bcd ef gh ";
assert(equal(splitter(a), ["a", "bcd", "ef", "gh"][]));