findSplitBefore

These functions find the first occurrence of needle in haystack and then split haystack as follows.

$(PANEL `findSplit` returns a tuple `result` containing $(I three) ranges. $(UL $(LI `result[0]` is the portion of `haystack` before `needle`) $(LI `result[1]` is the portion of `haystack` that matches `needle`) $(LI `result[2]` is the portion of `haystack` after the match.) ) If `needle` was not found, `result[0]` comprehends `haystack` entirely and `result[1]` and `result[2]` are empty. `findSplitBefore` returns a tuple `result` containing two ranges. $(UL $(LI `result[0]` is the portion of `haystack` before `needle`) $(LI `result[1]` is the balance of `haystack` starting with the match.) ) If `needle` was not found, `result[0]` comprehends `haystack` entirely and `result[1]` is empty. `findSplitAfter` returns a tuple `result` containing two ranges. $(UL $(LI `result[0]` is the portion of `haystack` up to and including the match) $(LI `result[1]` is the balance of `haystack` starting after the match.) ) If `needle` was not found, `result[0]` is empty and `result[1]` is `haystack`. )

In all cases, the concatenation of the returned ranges spans the entire haystack.

findSplitBefore
(
alias pred = "a == b"
R1
R2
)

Parameters

pred

Predicate to compare 2 elements.

haystack R1

The forward range to search.

needle R2

The forward range to look for.

Return Value

Type: auto

A sub-type of std.typecons.Tuple of the split portions of haystack (see above for details). This sub-type of Tuple defines opCast!bool, which returns true when the separating needle was found and false otherwise.

Examples

Returning a subtype of std.typecons.Tuple enables the following convenient idiom:

// findSplit returns a triplet
if (auto split = "dlang-rocks".findSplit("-"))
{
    assert(split[0] == "dlang");
    assert(split[1] == "-");
    assert(split[2] == "rocks");
}
else assert(0);

// findSplitBefore returns 2 ranges
if (const split = [2, 3, 2, 3, 4, 1].findSplitBefore!"a > b"([2, 2]))
{
    assert(split[0] == [2, 3, 2]);
    // [3, 4] each greater than [2, 2]
    assert(split[1] == [3, 4, 1]);
}
else assert(0);
import std.range.primitives : empty;

auto a = "Carl Sagan Memorial Station";
auto r = findSplit(a, "Velikovsky");
import std.typecons : isTuple;
static assert(isTuple!(typeof(r.asTuple)));
static assert(isTuple!(typeof(r)));
assert(!r);
assert(r[0] == a);
assert(r[1].empty);
assert(r[2].empty);
r = findSplit(a, " ");
assert(r[0] == "Carl");
assert(r[1] == " ");
assert(r[2] == "Sagan Memorial Station");
if (const r1 = findSplitBefore(a, "Sagan"))
{
    assert(r1);
    assert(r1[0] == "Carl ");
    assert(r1[1] == "Sagan Memorial Station");
}
if (const r2 = findSplitAfter(a, "Sagan"))
{
    assert(r2);
    assert(r2[0] == "Carl Sagan");
    assert(r2[1] == " Memorial Station");
}

Use std.range.only to find single elements:

import std.range : only;
assert([1, 2, 3, 4].findSplitBefore(only(3))[0] == [1, 2]);

See Also

Meta