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.

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 splitter(alias pred, Flag!("keepSeparators") keepSeparators = No.keepSeparators, Range, Separator) (
  Range r,
  Separator s
)
if (is(typeof(binaryFun!pred(r.front, s)) : bool) && (hasSlicing!Range && hasLength!Range || isNarrowString!Range));

auto splitter(alias pred, Flag!("keepSeparators") keepSeparators = No.keepSeparators, 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 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.empty) 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

NameDescription
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 .length 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
keepSeparators The flag for deciding if the separators are kept

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 keepSeparators is equal to Yes.keepSeparators the output will also contain the separators.

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, split for a version that splits eagerly and splitWhen, which compares adjacent elements instead of element against separator.

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

Basic splitting with characters and numbers and keeping sentinels.

import std.algorithm.comparison : equal;
import std.typecons : Yes;

assert("a|bc|def".splitter!("a == b", Yes.keepSeparators)('|')
    .equal([ "a", "|", "bc", "|", "def" ]));

int[] a = [1, 0, 2, 3, 0, 4, 5, 6];
int[][] w = [ [1], [0], [2, 3], [0], [4, 5, 6] ];
assert(a.splitter!("a == b", Yes.keepSeparators)(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

Adjacent separators and keeping sentinels.

import std.algorithm.comparison : equal;
import std.typecons : Yes;

assert("|ab|".splitter!("a == b", Yes.keepSeparators)('|')
    .equal([ "", "|", "ab", "|", "" ]));
assert("ab".splitter!("a == b", Yes.keepSeparators)('|')
    .equal([ "ab" ]));

assert("a|b||c".splitter!("a == b", Yes.keepSeparators)('|')
    .equal([ "a", "|", "b", "|", "", "|", "c" ]));
assert("hello  world".splitter!("a == b", Yes.keepSeparators)(' ')
    .equal([ "hello", " ", "", " ", "world" ]));

auto a = [ 1, 2, 0, 0, 3, 0, 4, 5, 0 ];
auto w = [ [1, 2], [0], [], [0], [3], [0], [4, 5], [0], [] ];
assert(a.splitter!("a == b", Yes.keepSeparators)(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

Empty and separator-only ranges and keeping sentinels.

import std.algorithm.comparison : equal;
import std.typecons : Yes;
import std.range : empty;

assert("".splitter!("a == b", Yes.keepSeparators)('|').empty);
assert("|".splitter!("a == b", Yes.keepSeparators)('|')
    .equal([ "", "|", "" ]));
assert("||".splitter!("a == b", Yes.keepSeparators)('|')
    .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

Use a range for splitting

import std.algorithm.comparison : equal;
import std.typecons : Yes;

assert("a=>bc=>def".splitter!("a == b", Yes.keepSeparators)("=>")
    .equal([ "a", "=>", "bc", "=>", "def" ]));
assert("a|b||c".splitter!("a == b", Yes.keepSeparators)("||")
    .equal([ "a|b", "||", "c" ]));
assert("hello  world".splitter!("a == b", Yes.keepSeparators)("  ")
    .equal([ "hello", "  ",  "world" ]));

int[] a = [ 1, 2, 0, 0, 3, 0, 4, 5, 0 ];
int[][] w = [ [1, 2], [0, 0], [3, 0, 4, 5, 0] ];
assert(a.splitter!("a == b", Yes.keepSeparators)([0, 0]).equal(w));

a = [ 0, 0 ];
assert(a.splitter!("a == b", Yes.keepSeparators)([0, 0])
    .equal([ (int[]).init, [0, 0], (int[]).init ]));

a = [ 0, 0, 1 ];
assert(a.splitter!("a == b", Yes.keepSeparators)([0, 0])
    .equal([ [], [0, 0], [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

Custom predicate functions.

import std.algorithm.comparison : equal;
import std.typecons : Yes;
import std.ascii : toLower;

assert("abXcdxef".splitter!("a.toLower == b", Yes.keepSeparators)('x')
    .equal([ "ab", "X", "cd", "x", "ef" ]));

auto w = [ [0], [1], [2] ];
assert(w.splitter!("a.front == b", Yes.keepSeparators)(1)
    .equal([ [[0]], [[1]], [[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

Leading separators, trailing separators, or no separators.

import std.algorithm.comparison : equal;
import std.typecons : Yes;

assert("|ab|".splitter!("a == b", Yes.keepSeparators)('|')
    .equal([ "", "|", "ab", "|", "" ]));
assert("ab".splitter!("a == b", Yes.keepSeparators)('|')
    .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

Splitter returns bidirectional ranges if the delimiter is a single element

import std.algorithm.comparison : equal;
import std.typecons : Yes;
import std.range : retro;
assert("a|bc|def".splitter!("a == b", Yes.keepSeparators)('|')
    .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 character-based range s into words, using whitespace as the delimiter.

auto splitter(Range) (
  Range s
)
if (isSomeString!Range || isRandomAccessRange!Range && hasLength!Range && hasSlicing!Range && !isConvertibleToString!Range && isSomeChar!(ElementEncodingType!Range));

This function is character-range specific and, contrary to splitter!(isWhite), runs of whitespace will be merged together (no empty tokens will be produced).

Parameters

NameDescription
s The character-based range to be split. Must be a string, or a random-access range of character types.

Returns

An input range of slices of the original range split by whitespace.

Example

import std.algorithm.comparison : equal;
auto a = " a     bcd   ef gh ";
assert(equal(splitter(a), ["a", "bcd", "ef", "gh"][]));

Authors

Andrei Alexandrescu

License

Boost License 1.0.