findSplit

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

findSplit returns a tuple result containing three ranges. result[0] is the portion of haystack before needle, result[1] is the portion of haystack that matches needle, and 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. result[0] is the portion of haystack before needle, and 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. result[0] is the portion of haystack up to and including the match, and 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.

If haystack is a random-access range, all three components of the tuple have the same type as haystack. Otherwise, haystack must be a forward range and the type of result[0] and result[1] is the same as std.range.takeExactly.

For more information about pred see find.

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

Parameters

pred

Predicate to use for comparing needle against haystack.

haystack R1

The range to search.

needle R2

What to look for.

Return Value

Type: auto

A sub-type of Tuple!() of the split portions of haystack (see above for details). This sub-type of Tuple!() has opCast defined for bool. This opCast 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);

// works with const aswell
if (const split = "dlang-rocks".findSplit("-"))
{
    assert(split[0] == "dlang");
    assert(split[1] == "-");
    assert(split[2] == "rocks");
}
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