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.searching
This is a submodule of std.algorithm.
It contains generic searching algorithms.
Function Name | Description |
---|---|
all | all!"a > 0"([1, 2, 3, 4]) returns true because all elements are positive |
any | any!"a > 0"([1, 2, -3, -4]) returns true because at least one element is positive |
balancedParens | balancedParens("((1 + 1) / 2)") returns true because the string has balanced parentheses. |
boyerMooreFinder | find("hello world", boyerMooreFinder("or")) returns "orld" using the Boyer-Moore algorithm. |
canFind | canFind("hello world", "or") returns true. |
count | Counts elements that are equal to a specified value or satisfy a predicate. count([1, 2, 1], 1) returns 2 and count!"a < 0"([1, -3, 0]) returns 1. |
countUntil | countUntil(a, b) returns the number of steps taken in a to reach b; for example, countUntil("hello!", "o") returns 4. |
commonPrefix | commonPrefix("parakeet", "parachute") returns "para". |
endsWith | endsWith("rocks", "ks") returns true. |
find | find("hello world", "or") returns "orld" using linear search. (For binary search refer to std.range.sortedRange.) |
findAdjacent | findAdjacent([1, 2, 3, 3, 4]) returns the subrange starting with two equal adjacent elements, i.e. [3, 3, 4]. |
findAmong | findAmong("abcd", "qcx") returns "cd" because 'c' is among "qcx". |
findSkip | If a = "abcde", then findSkip(a, "x") returns false and leaves a unchanged, whereas findSkip(a, "c") advances a to "de" and returns true. |
findSplit | findSplit("abcdefg", "de") returns the three ranges "abc", "de", and "fg". |
findSplitAfter | findSplitAfter("abcdefg", "de") returns the two ranges "abcde" and "fg". |
findSplitBefore | findSplitBefore("abcdefg", "de") returns the two ranges "abc" and "defg". |
minCount | minCount([2, 1, 1, 4, 1]) returns tuple(1, 3). |
minPos | minPos([2, 3, 1, 3, 4, 1]) returns the subrange [1, 3, 4, 1], i.e., positions the range at the first occurrence of its minimal element. |
mismatch | mismatch("parakeet", "parachute") returns the two ranges "keet" and "chute". |
skipOver | Assume a = "blah". Then skipOver(a, "bi") leaves a unchanged and returns false, whereas skipOver(a, "bl") advances a to refer to "ah" and returns true. |
startsWith | startsWith("hello, world", "hello") returns true. |
until | Lazily iterates a range until a specific value is found. |
License:
Authors:
Source: std/algorithm/searching.d
- template all(alias pred = "a")
- Checks if all of the elements verify pred.Examples:
assert( all!"a & 1"([1, 3, 5, 7, 9])); assert(!all!"a & 1"([1, 2, 3, 5, 7, 9]));
Examples: - template any(alias pred = "a")
- Checks if any of the elements verifies pred. !any can be used to verify that none of the elements verify pred.Examples:
import std.ascii : isWhite; assert( all!(any!isWhite)(["a a", "b b"])); assert(!any!(all!isWhite)(["a a", "b b"]));
Examples:any can also be used without a predicate, if its items can be evaluated to true or false in a conditional statement. !any can be a convenient way to quickly test that none of the elements of a range evaluate to true.int[3] vals1 = [0, 0, 0]; assert(!any(vals1[])); //none of vals1 evaluate to true int[3] vals2 = [2, 0, 2]; assert( any(vals2[])); assert(!all(vals2[])); int[3] vals3 = [3, 3, 3]; assert( any(vals3[])); assert( all(vals3[]));
- bool balancedParens(Range, E)(Range r, E lPar, E rPar, size_t maxNestingLevel = size_t.max) if (isInputRange!Range && is(typeof(r.front == lPar)));
- Checks whether r has "balanced parentheses", i.e. all instances of lPar are closed by corresponding instances of rPar. The parameter maxNestingLevel controls the nesting level allowed. The most common uses are the default or 0. In the latter case, no nesting is allowed.Parameters:
Range r The range to check. E lPar The element corresponding with a left (opening) parenthesis. E rPar The element corresponding with a right (closing) parenthesis. size_t maxNestingLevel The maximum allowed nesting level. Returns:true if the given range has balanced parenthesis within the given maximum nesting level; false otherwise.Examples:auto s = "1 + (2 * (3 + 1 / 2)"; assert(!balancedParens(s, '(', ')')); s = "1 + (2 * (3 + 1) / 2)"; assert(balancedParens(s, '(', ')')); s = "1 + (2 * (3 + 1) / 2)"; assert(!balancedParens(s, '(', ')', 0)); s = "1 + (2 * 3 + 1) / (2 - 5)"; assert(balancedParens(s, '(', ')', 0));
- BoyerMooreFinder!(binaryFun!pred, Range) boyerMooreFinder(alias pred = "a == b", Range)(Range needle) if (isRandomAccessRange!Range || isSomeString!Range);
struct BoyerMooreFinder(alias pred, Range); - Sets up Boyer-Moore matching for use with find below. By default, elements are compared for equality.Parameters:
pred Predicate used to compare elements. Range needle A random-access range with length and slicing. - auto commonPrefix(alias pred = "a == b", R1, R2)(R1 r1, R2 r2) if (isForwardRange!R1 && isInputRange!R2 && !isNarrowString!R1 && is(typeof(binaryFun!pred(r1.front, r2.front))));
auto commonPrefix(alias pred, R1, R2)(R1 r1, R2 r2) if (isNarrowString!R1 && isInputRange!R2 && is(typeof(binaryFun!pred(r1.front, r2.front))));
auto commonPrefix(R1, R2)(R1 r1, R2 r2) if (isNarrowString!R1 && isInputRange!R2 && !isNarrowString!R2 && is(typeof(r1.front == r2.front)));
auto commonPrefix(R1, R2)(R1 r1, R2 r2) if (isNarrowString!R1 && isNarrowString!R2); - Returns the common prefix of two ranges.Parameters:
pred The predicate to use in comparing elements for commonality. Defaults to equality "a == b". R1 r1 A forward range of elements. R2 r2 An input range of elements. Returns:A slice of r1 which contains the characters that both ranges start with, if the first argument is a string; otherwise, the same as the result of takeExactly(r1, n), where n is the number of elements in the common prefix of both ranges.See Also:Examples:assert(commonPrefix("hello, world", "hello, there") == "hello, ");
- size_t count(alias pred = "a == b", Range, E)(Range haystack, E needle) if (isInputRange!Range && !isInfinite!Range && is(typeof(binaryFun!pred(haystack.front, needle)) : bool));
size_t count(alias pred = "a == b", R1, R2)(R1 haystack, R2 needle) if (isForwardRange!R1 && !isInfinite!R1 && isForwardRange!R2 && is(typeof(binaryFun!pred(haystack.front, needle.front)) : bool));
size_t count(alias pred = "true", R)(R haystack) if (isInputRange!R && !isInfinite!R && is(typeof(unaryFun!pred(haystack.front)) : bool)); - The first version counts the number of elements x in r for which pred(x, value) is true. pred defaults to equality. Performs Ο(haystack.length) evaluations of pred.The second version returns the number of times needle occurs in haystack. Throws an exception if needle.empty, as the count of the empty range in any range would be infinite. Overlapped counts are not considered, for example count("aaa", "aa") is 1, not 2. The third version counts the elements for which pred(x) is true. Performs Ο(haystack.length) evaluations of pred.Parameters:
pred The predicate to evaluate. Range haystack The range to count. E needle The element or sub-range to count in the haystack. Returns:The number of positions in the haystack for which pred returned true.Examples:import std.uni : toLower; // count elements in range int[] a = [ 1, 2, 4, 3, 2, 5, 3, 2, 4 ]; assert(count(a, 2) == 3); assert(count!("a > b")(a, 2) == 5); // count range in range assert(count("abcadfabf", "ab") == 2); assert(count("ababab", "abab") == 1); assert(count("ababab", "abx") == 0); // fuzzy count range in range assert(count!((a, b) => std.uni.toLower(a) == std.uni.toLower(b))("AbcAdFaBf", "ab") == 2); // count predicate in range assert(count!("a > 1")(a) == 8);
- ptrdiff_t countUntil(alias pred = "a == b", R, Rs...)(R haystack, Rs needles) if (isForwardRange!R && Rs.length > 0 && isForwardRange!(Rs[0]) == isInputRange!(Rs[0]) && is(typeof(startsWith!pred(haystack, needles[0]))) && (Rs.length == 1 || is(typeof(countUntil!pred(haystack, needles[1..$])))));
ptrdiff_t countUntil(alias pred = "a == b", R, N)(R haystack, N needle) if (isInputRange!R && is(typeof(binaryFun!pred(haystack.front, needle)) : bool)); - Counts elements in the given forward range until the given predicate is true for one of the given needles.Parameters:
pred The predicate for determining when to stop counting. R haystack The input range to be counted. Rs needles Either a single element, or a forward range of elements, to be evaluated in turn against each element in haystack under the given predicate. Returns:The number of elements which must be popped from the front of haystack before reaching an element for which startsWith!pred(haystack, needles) is true. If startsWith!pred(haystack, needles) is not true for any element in haystack, then -1 is returned.Examples:assert(countUntil("hello world", "world") == 6); assert(countUntil("hello world", 'r') == 8); assert(countUntil("hello world", "programming") == -1); assert(countUntil("日本語", "本語") == 1); assert(countUntil("日本語", '語') == 2); assert(countUntil("日本語", "五") == -1); assert(countUntil("日本語", '五') == -1); assert(countUntil([0, 7, 12, 22, 9], [12, 22]) == 2); assert(countUntil([0, 7, 12, 22, 9], 9) == 4); assert(countUntil!"a > b"([0, 7, 12, 22, 9], 20) == 3);
- ptrdiff_t countUntil(alias pred, R)(R haystack) if (isInputRange!R && is(typeof(unaryFun!pred(haystack.front)) : bool));
- Similar to the previous overload of countUntil, except that this one evaluates only the predicate pred.Parameters:
pred Predicate to when to stop counting. R haystack An input range of elements to be counted. Returns:The number of elements which must be popped from haystack before pred(haystack.front) is true.Examples:import std.ascii : isDigit; import std.uni : isWhite; assert(countUntil!(std.uni.isWhite)("hello world") == 5); assert(countUntil!(std.ascii.isDigit)("hello world") == -1); assert(countUntil!"a > 20"([0, 7, 12, 22, 9]) == 3);
- uint endsWith(alias pred = "a == b", Range, Needles...)(Range doesThisEnd, Needles withOneOfThese) if (isBidirectionalRange!Range && Needles.length > 1 && is(typeof(.endsWith!pred(doesThisEnd, withOneOfThese[0])) : bool) && is(typeof(.endsWith!pred(doesThisEnd, withOneOfThese[1..$])) : uint));
bool endsWith(alias pred = "a == b", R1, R2)(R1 doesThisEnd, R2 withThis) if (isBidirectionalRange!R1 && isBidirectionalRange!R2 && is(typeof(binaryFun!pred(doesThisEnd.back, withThis.back)) : bool));
bool endsWith(alias pred = "a == b", R, E)(R doesThisEnd, E withThis) if (isBidirectionalRange!R && is(typeof(binaryFun!pred(doesThisEnd.back, withThis)) : bool)); - Checks if the given range ends with (one of) the given needle(s). The reciprocal of startsWith.Parameters:
pred The predicate to use for comparing elements between the range and the needle(s). Range doesThisEnd The bidirectional range to check. Needles withOneOfThese The needles to check against, which may be single elements, or bidirectional ranges of elements. R2 withThis The single element to check. Returns:0 if the needle(s) do not occur at the end of the given range; otherwise the position of the matching needle, that is, 1 if the range ends with withOneOfThese[0], 2 if it ends with withOneOfThese[1], and so on.Examples:assert(endsWith("abc", "")); assert(!endsWith("abc", "b")); assert(endsWith("abc", "a", 'c') == 2); assert(endsWith("abc", "c", "a") == 1); assert(endsWith("abc", "c", "c") == 1); assert(endsWith("abc", "bc", "c") == 2); assert(endsWith("abc", "x", "c", "b") == 2); assert(endsWith("abc", "x", "aa", "bc") == 3); assert(endsWith("abc", "x", "aaa", "sab") == 0); assert(endsWith("abc", "x", "aaa", 'c', "sab") == 3);
- InputRange find(alias pred = "a == b", InputRange, Element)(InputRange haystack, Element needle) if (isInputRange!InputRange && is(typeof(binaryFun!pred(haystack.front, needle)) : bool));
- Finds an individual element in an input range. Elements of haystack are compared with needle by using predicate pred. Performs Ο(walkLength(haystack)) evaluations of pred.To find the last occurrence of needle in haystack, call find(retro(haystack), needle). See std.range.retro.Parameters:
pred The predicate for comparing each element with the needle, defaulting to "a == b". The negated predicate "a != b" can be used to search instead for the first element not matching the needle. InputRange haystack The input range searched in. Element needle The element searched for. Constraints: isInputRange!InputRange && is(typeof(binaryFun!pred(haystack.front, needle) : bool))
Returns:haystack advanced such that the front element is the one searched for; that is, until binaryFun!pred(haystack.front, needle) is true. If no such position exists, returns an empty haystack.See Also:Examples:import std.algorithm.comparison : equal; import std.container : SList; assert(find("hello, world", ',') == ", world"); assert(find([1, 2, 3, 5], 4) == []); assert(equal(find(SList!int(1, 2, 3, 4, 5)[], 4), SList!int(4, 5)[])); assert(find!"a > b"([1, 2, 3, 5], 2) == [3, 5]); auto a = [ 1, 2, 3 ]; assert(find(a, 5).empty); // not found assert(!find(a, 2).empty); // found // Case-insensitive find of a string string[] s = [ "Hello", "world", "!" ]; assert(!find!("toLower(a) == b")(s, "hello").empty);
- InputRange find(alias pred, InputRange)(InputRange haystack) if (isInputRange!InputRange);
- Advances the input range haystack by calling haystack.popFront until either pred(haystack.front), or haystack.empty. Performs Ο(haystack.length) evaluations of pred.To find the last element of a bidirectional haystack satisfying pred, call find!(pred)(retro(haystack)). See std.range.retro.Parameters:
pred The predicate for determining if a given element is the one being searched for. InputRange haystack The input range to search in. Returns:haystack advanced such that the front element is the one searched for; that is, until binaryFun!pred(haystack.front, needle) is true. If no such position exists, returns an empty haystack.See Also:Examples:auto arr = [ 1, 2, 3, 4, 1 ]; assert(find!("a > 2")(arr) == [ 3, 4, 1 ]); // with predicate alias bool pred(int x) { return x + 1 > 1.5; } assert(find!(pred)(arr) == arr);
- R1 find(alias pred = "a == b", R1, R2)(R1 haystack, R2 needle) if (isForwardRange!R1 && isForwardRange!R2 && is(typeof(binaryFun!pred(haystack.front, needle.front)) : bool) && !isRandomAccessRange!R1);
- Finds the first occurrence of a forward range in another forward range.Performs Ο(walkLength(haystack) * walkLength(needle)) comparisons in the worst case. There are specializations that improve performance by taking advantage of bidirectional or random access in the given ranges (where possible), depending on the statistics of the two ranges' content.Parameters:
pred The predicate to use for comparing respective elements from the haystack and the needle. Defaults to simple equality "a == b". R1 haystack The forward range searched in. R2 needle The forward range searched for. Returns:haystack advanced such that needle is a prefix of it (if no such position exists, returns haystack advanced to termination).Examples:import std.container : SList; assert(find("hello, world", "World").empty); assert(find("hello, world", "wo") == "world"); assert([1, 2, 3, 4].find(SList!int(2, 3)[]) == [2, 3, 4]); alias C = Tuple!(int, "x", int, "y"); auto a = [C(1,0), C(2,0), C(3,1), C(4,0)]; assert(a.find!"a.x == b"([2, 3]) == [C(2,0), C(3,1), C(4,0)]); assert(a[1 .. $].find!"a.x == b"([2, 3]) == [C(2,0), C(3,1), C(4,0)]);
- Tuple!(Range, size_t) find(alias pred = "a == b", Range, Ranges...)(Range haystack, Ranges needles) if (Ranges.length > 1 && is(typeof(startsWith!pred(haystack, needles))));
- Finds two or more needles into a haystack. The predicate pred is used throughout to compare elements. By default, elements are compared for equality.Parameters:
pred The predicate to use for comparing elements. Range haystack The target of the search. Must be an input range. If any of needles is a range with elements comparable to elements in haystack, then haystack must be a forward range such that the search can backtrack. Ranges needles One or more items to search for. Each of needles must be either comparable to one element in haystack, or be itself a forward range with elements comparable with elements in haystack. Returns:A tuple containing haystack positioned to match one of the needles and also the 1-based index of the matching element in needles (0 if none of needles matched, 1 if needles[0] matched, 2 if needles[1] matched...). The first needle to be found will be the one that matches. If multiple needles are found at the same spot in the range, then the shortest one is the one which matches (if multiple needles of the same length are found at the same spot (e.g "a" and 'a'), then the left-most of them in the argument list matches). The relationship between haystack and needles simply means that one can e.g. search for individual ints or arrays of ints in an array of ints. In addition, if elements are individually comparable, searches of heterogeneous types are allowed as well: a double[] can be searched for an int or a short[], and conversely a long can be searched for a float or a double[]. This makes for efficient searches without the need to coerce one side of the comparison into the other's side type. The complexity of the search is Ο(haystack.length * max(needles.length)). (For needles that are individual items, length is considered to be 1.) The strategy used in searching several subranges at once maximizes cache usage by moving in haystack as few times as possible.Examples:int[] a = [ 1, 4, 2, 3 ]; assert(find(a, 4) == [ 4, 2, 3 ]); assert(find(a, [ 1, 4 ]) == [ 1, 4, 2, 3 ]); assert(find(a, [ 1, 3 ], 4) == tuple([ 4, 2, 3 ], 2)); // Mixed types allowed if comparable assert(find(a, 5, [ 1.2, 3.5 ], 2.0) == tuple([ 2, 3 ], 3));
- Range1 find(Range1, alias pred, Range2)(Range1 haystack, BoyerMooreFinder!(pred, Range2) needle);
-
Parameters:
Range1 haystack A random-access range with length and slicing. BoyerMooreFinder!(pred, Range2) needle A BoyerMooreFinder. Returns:haystack advanced such that needle is a prefix of it (if no such position exists, returns haystack advanced to termination).Examples:int[] a = [ -1, 0, 1, 2, 3, 4, 5 ]; int[] b = [ 1, 2, 3 ]; assert(find(a, boyerMooreFinder(b)) == [ 1, 2, 3, 4, 5 ]); assert(find(b, boyerMooreFinder(a)).empty);
- template canFind(alias pred = "a == b")
- Convenience function. Like find, but only returns whether or not the search was successful.See Also:among for checking a value against multiple possibilities.Examples:
assert(canFind([0, 1, 2, 3], 2) == true); assert(canFind([0, 1, 2, 3], [1, 2], [2, 3])); assert(canFind([0, 1, 2, 3], [1, 2], [2, 3]) == 1); assert(canFind([0, 1, 2, 3], [1, 7], [2, 3])); assert(canFind([0, 1, 2, 3], [1, 7], [2, 3]) == 2); assert(canFind([0, 1, 2, 3], 4) == false); assert(!canFind([0, 1, 2, 3], [1, 3], [2, 4])); assert(canFind([0, 1, 2, 3], [1, 3], [2, 4]) == 0);
- bool canFind(Range)(Range haystack) if (is(typeof(find!pred(haystack))));
- Returns true if and only if any value v found in the input range range satisfies the predicate pred. Performs (at most) Ο(haystack.length) evaluations of pred.
- bool canFind(Range, Element)(Range haystack, Element needle) if (is(typeof(find!pred(haystack, needle))));
- Returns true if and only if needle can be found in range. Performs Ο(haystack.length) evaluations of pred.
- size_t canFind(Range, Ranges...)(Range haystack, Ranges needles) if (Ranges.length > 1 && allSatisfy!(isForwardRange, Ranges) && is(typeof(find!pred(haystack, needles))));
- Returns the 1-based index of the first needle found in haystack. If no needle is found, then 0 is returned.So, if used directly in the condition of an if statement or loop, the result will be true if one of the needles is found and false if none are found, whereas if the result is used elsewhere, it can either be cast to bool for the same effect or used to get which needle was found first without having to deal with the tuple that LREF find returns for the same operation.
- Range findAdjacent(alias pred = "a == b", Range)(Range r) if (isForwardRange!Range);
- Advances r until it finds the first two adjacent elements a, b that satisfy pred(a, b). Performs Ο(r.length) evaluations of pred.Parameters:
pred The predicate to satisfy. Range r A forward range to search in. Returns:r advanced to the first occurrence of two adjacent elements that satisfy the given predicate. If there are no such two elements, returns r advanced until empty.See Also:Examples:int[] a = [ 11, 10, 10, 9, 8, 8, 7, 8, 9 ]; auto r = findAdjacent(a); assert(r == [ 10, 10, 9, 8, 8, 7, 8, 9 ]); auto p = findAdjacent!("a < b")(a); assert(p == [ 7, 8, 9 ]);
- Range1 findAmong(alias pred = "a == b", Range1, Range2)(Range1 seq, Range2 choices) if (isInputRange!Range1 && isForwardRange!Range2);
- Searches the given range for an element that matches one of the given choices.Advances seq by calling seq.popFront until either find!(pred)(choices, seq.front) is true, or seq becomes empty. Performs Ο(seq.length * choices.length) evaluations of pred.Parameters:
pred The predicate to use for determining a match. Range1 seq The input range to search. Range2 choices A forward range of possible choices. Returns:seq advanced to the first matching element, or until empty if there are no matching elements.See Also:Examples:int[] a = [ -1, 0, 1, 2, 3, 4, 5 ]; int[] b = [ 3, 1, 2 ]; assert(findAmong(a, b) == a[2 .. $]);
- bool findSkip(alias pred = "a == b", R1, R2)(ref R1 haystack, R2 needle) if (isForwardRange!R1 && isForwardRange!R2 && is(typeof(binaryFun!pred(haystack.front, needle.front))));
- Finds needle in haystack and positions haystack right after the first occurrence of needle.Parameters:
R1 haystack The forward range to search in. R2 needle The forward range to search for. Returns:true if the needle was found, in which case haystack is positioned after the end of the first occurrence of needle; otherwise false, leaving haystack untouched.Examples:// Needle is found; s is replaced by the substring following the first // occurrence of the needle. string s = "abcdef"; assert(findSkip(s, "cd") && s == "ef"); // Needle is not found; s is left untouched. s = "abcdef"; assert(!findSkip(s, "cxd") && s == "abcdef"); // If the needle occurs at the end of the range, the range is left empty. s = "abcdef"; assert(findSkip(s, "def") && s.empty);
- auto findSplit(alias pred = "a == b", R1, R2)(R1 haystack, R2 needle) if (isForwardRange!R1 && isForwardRange!R2);
auto findSplitBefore(alias pred = "a == b", R1, R2)(R1 haystack, R2 needle) if (isForwardRange!R1 && isForwardRange!R2);
auto findSplitAfter(alias pred = "a == b", R1, R2)(R1 haystack, R2 needle) if (isForwardRange!R1 && isForwardRange!R2); - 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.Parameters:
pred Predicate to use for comparing needle against haystack. R1 haystack The range to search. R2 needle What to look for. Returns: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 (!result[1].empty) and false otherwise. This enables the convenient idiom shown in the following example.Example:
if (const split = haystack.findSplit(needle)) { doSomethingWithSplit(split); }
Examples: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"); auto r1 = findSplitBefore(a, "Sagan"); assert(r1); assert(r1[0] == "Carl ", r1[0]); assert(r1[1] == "Sagan Memorial Station"); auto r2 = findSplitAfter(a, "Sagan"); assert(r2); assert(r2[0] == "Carl Sagan"); assert(r2[1] == " Memorial Station");
- Tuple!(ElementType!Range, size_t) minCount(alias pred = "a < b", Range)(Range range) if (isInputRange!Range && !isInfinite!Range && is(typeof(binaryFun!pred(range.front, range.front))));
- Parameters:
pred The ordering predicate to use to determine the minimal element. Range range The input range to count. Returns:The minimum element of a range together with the number of occurrences. The function can actually be used for counting the maximum or any other ordering predicate (that's why maxCount is not provided).Examples:import std.conv : text; debug(std_algorithm) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " done."); int[] a = [ 2, 3, 4, 1, 2, 4, 1, 1, 2 ]; // Minimum is 1 and occurs 3 times assert(minCount(a) == tuple(1, 3)); // Maximum is 4 and occurs 2 times assert(minCount!("a > b")(a) == tuple(4, 2));
- Range minPos(alias pred = "a < b", Range)(Range range) if (isForwardRange!Range && !isInfinite!Range && is(typeof(binaryFun!pred(range.front, range.front))));
- Parameters:
pred The ordering predicate to use to determine the minimal element. Range range The input range to search. Returns:The position of the minimum element of forward range range, i.e. a subrange of range starting at the position of its smallest element and with the same ending as range. The function can actually be used for finding the maximum or any other ordering predicate (that's why maxPos is not provided).Examples:int[] a = [ 2, 3, 4, 1, 2, 4, 1, 1, 2 ]; // Minimum is 1 and first occurs in position 3 assert(minPos(a) == [ 1, 2, 4, 1, 1, 2 ]); // Maximum is 4 and first occurs in position 2 assert(minPos!("a > b")(a) == [ 4, 1, 2, 4, 1, 1, 2 ]);
- bool skipOver(R1, R2)(ref R1 r1, R2 r2) if (isForwardRange!R1 && isInputRange!R2 && is(typeof(r1.front == r2.front)));
bool skipOver(alias pred, R1, R2)(ref R1 r1, R2 r2) if (is(typeof(binaryFun!pred(r1.front, r2.front))) && isForwardRange!R1 && isInputRange!R2); - Skip over the initial portion of the first given range that matches the second range, or do nothing if there is no match.Parameters:
pred The predicate that determines whether elements from each respective range match. Defaults to equality "a == b". R1 r1 The forward range to move forward. R2 r2 The input range representing the initial segment of r1 to skip over. Returns:true if the initial segment of r1 matches r2, and r1 has been advanced to the point past this segment; otherwise false, and r1 is left in its original position.Examples:import std.algorithm.comparison : equal; auto s1 = "Hello world"; assert(!skipOver(s1, "Ha")); assert(s1 == "Hello world"); assert(skipOver(s1, "Hell") && s1 == "o world"); string[] r1 = ["abc", "def", "hij"]; dstring[] r2 = ["abc"d]; assert(!skipOver!((a, b) => a.equal(b))(r1, ["def"d])); assert(r1 == ["abc", "def", "hij"]); assert(skipOver!((a, b) => a.equal(b))(r1, r2)); assert(r1 == ["def", "hij"]);
- bool skipOver(R, E)(ref R r, E e) if (isInputRange!R && is(typeof(r.front == e) : bool));
bool skipOver(alias pred, R, E)(ref R r, E e) if (is(typeof(binaryFun!pred(r.front, e))) && isInputRange!R); - Skip over the first element of the given range if it matches the given element, otherwise do nothing.Parameters:
pred The predicate that determines whether an element from the range matches the given element. R r The input range to skip over. E e The element to match. Returns:true if the first element matches the given element according to the given predicate, and the range has been advanced by one element; otherwise false, and the range is left untouched.Examples:import std.algorithm.comparison : equal; auto s1 = "Hello world"; assert(!skipOver(s1, 'a')); assert(s1 == "Hello world"); assert(skipOver(s1, 'H') && s1 == "ello world"); string[] r = ["abc", "def", "hij"]; dstring e = "abc"d; assert(!skipOver!((a, b) => a.equal(b))(r, "def"d)); assert(r == ["abc", "def", "hij"]); assert(skipOver!((a, b) => a.equal(b))(r, e)); assert(r == ["def", "hij"]); auto s2 = ""; assert(!s2.skipOver('a'));
- uint startsWith(alias pred = "a == b", Range, Needles...)(Range doesThisStart, Needles withOneOfThese) if (isInputRange!Range && Needles.length > 1 && is(typeof(.startsWith!pred(doesThisStart, withOneOfThese[0])) : bool) && is(typeof(.startsWith!pred(doesThisStart, withOneOfThese[1..$])) : uint));
bool startsWith(alias pred = "a == b", R1, R2)(R1 doesThisStart, R2 withThis) if (isInputRange!R1 && isInputRange!R2 && is(typeof(binaryFun!pred(doesThisStart.front, withThis.front)) : bool));
bool startsWith(alias pred = "a == b", R, E)(R doesThisStart, E withThis) if (isInputRange!R && is(typeof(binaryFun!pred(doesThisStart.front, withThis)) : bool)); - Checks whether the given input range starts with (one of) the given needle(s).Parameters:
pred Predicate to use in comparing the elements of the haystack and the needle(s). Range doesThisStart The input range to check. Needles withOneOfThese The needles against which the range is to be checked, which may be individual elements or input ranges of elements. R2 withThis The single needle to check, which may be either a single element or an input range of elements. Returns:0 if the needle(s) do not occur at the beginning of the given range; otherwise the position of the matching needle, that is, 1 if the range starts with withOneOfThese[0], 2 if it starts with withOneOfThese[1], and so on. In the case where doesThisStart starts with multiple of the ranges or elements in withOneOfThese, then the shortest one matches (if there are two which match which are of the same length (e.g. "a" and 'a'), then the left-most of them in the argument list matches).Examples:assert(startsWith("abc", "")); assert(startsWith("abc", "a")); assert(!startsWith("abc", "b")); assert(startsWith("abc", 'a', "b") == 1); assert(startsWith("abc", "b", "a") == 2); assert(startsWith("abc", "a", "a") == 1); assert(startsWith("abc", "ab", "a") == 2); assert(startsWith("abc", "x", "a", "b") == 2); assert(startsWith("abc", "x", "aa", "ab") == 3); assert(startsWith("abc", "x", "aaa", "sab") == 0); assert(startsWith("abc", "x", "aaa", "a", "sab") == 3); alias C = Tuple!(int, "x", int, "y"); assert(startsWith!"a.x == b"([ C(1,1), C(1,2), C(2,2) ], [1, 1])); assert(startsWith!"a.x == b"([ C(1,1), C(2,1), C(2,2) ], [1, 1], [1, 2], [1, 3]) == 2);
- enum OpenRight: int;
- Interval option specifier for until (below) and others.
- Until!(pred, Range, Sentinel) until(alias pred = "a == b", Range, Sentinel)(Range range, Sentinel sentinel, OpenRight openRight = OpenRight.yes) if (!is(Sentinel == OpenRight));
Until!(pred, Range, void) until(alias pred, Range)(Range range, OpenRight openRight = OpenRight.yes); - Lazily iterates range until the element e for which pred(e, sentinel) is true.Parameters:
pred Predicate to determine when to stop. Range range The input range to iterate over. Sentinel sentinel The element to stop at. OpenRight openRight Determines whether the element for which the given predicate is true should be included in the resulting range (OpenRight.no), or not (OpenRight.yes). Returns:An input range that iterates over the original range's elements, but ends when the specified predicate becomes true. If the original range is a forward range or higher, this range will be a forward range.Examples:import std.algorithm.comparison : equal; int[] a = [ 1, 2, 4, 7, 7, 2, 4, 7, 3, 5]; assert(equal(a.until(7), [1, 2, 4][])); assert(equal(a.until(7, OpenRight.no), [1, 2, 4, 7][]));