| Function Name | Description |
|---|---|
| all | all!"a > 0"([1, 2, 3, 4]) returnstrue because all elements are positive |
| any | any!"a > 0"([1, 2, -3, -4]) returnstrue because at least one element is positive |
| balancedParens | balancedParens("((1 + 1) / 2)", '(', ')') returnstrue because the string has balanced parentheses. |
| boyerMooreFinder | find("hello world", boyerMooreFinder("or")) returns"orld" using the Boyer-Moore algorithm. |
| canFind | canFind("hello world", "or") returnstrue. |
| count | Counts all elements or elements matching a predicate, specific element or sub-range. count([1, 2, 1]) returns3,count([1, 2, 1], 1) returns2 andcount!"a < 0"([1, -3, 0]) returns1. |
| countUntil | countUntil(a, b) returns the number of steps taken ina to reachb; for example,countUntil("hello!", "o") returns4. |
| commonPrefix | commonPrefix("parakeet", "parachute") returns"para". |
| endsWith | endsWith("rocks", "ks") returnstrue. |
| extrema | extrema([2, 1, 3, 5, 4]) returns[1, 5]. |
| find | find("hello world", "or") returns"orld" using linear search. (For binary search refer tostd.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 | Ifa = "abcde", thenfindSkip(a, "x") returnsfalse and leavesa unchanged, whereasfindSkip(a, "c") advancesa to"de" and returnstrue. |
| findSplit | findSplit("abcdefg", "de") returns a tuple of three ranges"abc","de", and"fg". |
| findSplitAfter | findSplitAfter("abcdefg", "de") returns a tuple of two ranges"abcde" and"fg". |
| findSplitBefore | findSplitBefore("abcdefg", "de") returns a tuple of two ranges"abc" and"defg". |
| minCount | minCount([2, 1, 1, 4, 1]) returnstuple(1, 3). |
| maxCount | maxCount([2, 4, 1, 4, 1]) returnstuple(4, 2). |
| minElement | Selects the minimal element of a range.minElement([3, 4, 1, 2]) returns1. |
| maxElement | Selects the maximal element of a range.maxElement([3, 4, 1, 2]) returns4. |
| minIndex | Index of the minimal element of a range.minIndex([3, 4, 1, 2]) returns2. |
| maxIndex | Index of the maximal element of a range.maxIndex([3, 4, 1, 2]) returns1. |
| 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. |
| maxPos | maxPos([2, 3, 1, 3, 4, 1]) returns the subrange[4, 1], i.e., positions the range at the first occurrence of its maximal element. |
| skipOver | Assumea = "blah". ThenskipOver(a, "bi") leavesa unchanged and returnsfalse, whereasskipOver(a, "bl") advancesa to refer to"ah" and returnstrue. |
| startsWith | startsWith("hello, world", "hello") returnstrue. |
| until | Lazily iterates a range until a specific value is found. |
all(alias pred = "a")assert(all!"a & 1"([1, 3, 5, 7, 9]));assert(!all!"a & 1"([1, 2, 3, 5, 7, 9]));
all can also be used without a predicate, if its items can beevaluated to true or false in a conditional statement. This can be aconvenient way to quickly evaluate thatall of the elements of a rangeare true.int[3] vals = [5, 3, 18];assert(all(vals[]));
all(Range)(Rangerange)range.front)))));range is empty orall values found inrange satisfy the predicatepred. Performs (at most)Ο(range.length) evaluations ofpred.any(alias pred = "a")any can be used to verify thatnone of the elements satisfypred.This is sometimes calledexists in other languages.import std.ascii : isWhite;assert( all!(any!isWhite)(["a a","b b"]));assert(!any!(all!isWhite)(["a a","b b"]));
any can also be used without a predicate, if its items can beevaluated to true or false in a conditional statement.!any can be aconvenient way to quickly test thatnone of the elements of a rangeevaluate to true.int[3] vals1 = [0, 0, 0];assert(!any(vals1[]));//none of vals1 evaluate to trueint[3] vals2 = [2, 0, 2];assert(any(vals2[]));assert(!all(vals2[]));int[3] vals3 = [3, 3, 3];assert(any(vals3[]));assert( all(vals3[]));
any(Range)(Rangerange)range.front)))));range is non-empty andany value found inrange satisfies the predicatepred. Performs (at most)Ο(range.length) evaluations ofpred.balancedParens(Range, E)(Ranger, ElPar, ErPar, size_tmaxNestingLevel = size_t.max)r.front ==lPar)));r has "balanced parentheses", i.e. all instancesoflPar are closed by corresponding instances ofrPar. TheparametermaxNestingLevel controls the nesting level allowed. Themost common uses are the default or0. In the latter case, nonesting is allowed.Ranger | The range to check. |
ElPar | The element corresponding with a left (opening) parenthesis. |
ErPar | The element corresponding with a right (closing) parenthesis. |
size_tmaxNestingLevel | The maximum allowed nesting level. |
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));s ="f(x) = ⌈x⌉";assert(balancedParens(s, '⌈', '⌉'));
BoyerMooreFinder(alias pred, Range);boyerMooreFinder(alias pred = "a == b", Range)(Rangeneedle)BoyerMooreFinder allocates GC memory.| pred | Predicate used to compare elements. |
Rangeneedle | A random-access range with length and slicing. |
BoyerMooreFinder that can be used withfind() to invoke the Boyer-Moore matching algorithm for finding ofneedle in a given haystack.auto bmFinder =boyerMooreFinder("TG");string r ="TAGTGCCTGA";// search for the first match in the haystack rr = bmFinder.beFound(r);writeln(r);// "TGCCTGA"// continue search in haystackr = bmFinder.beFound(r[2 .. $]);writeln(r);// "TGA"
needle);beFound(Rangehaystack) scope;length();opDollar = length;commonPrefix(alias pred = "a == b", R1, R2)(R1r1, R2r2)r1.front,r2.front))));commonPrefix(alias pred, R1, R2)(R1r1, R2r2)r1.front,r2.front))));commonPrefix(R1, R2)(R1r1, R2r2)r1.front ==r2.front)));commonPrefix(R1, R2)(R1r1, R2r2)| pred | The predicate to use in comparing elements for commonality. Defaults to equality"a == b". |
R1r1 | Aforward range of elements. |
R2r2 | Aninput range of elements. |
r1 which contains the characters that both ranges start with,if the first argument is a string; otherwise, the same as the result oftakeExactly(r1, n), wheren is the number of elements in the commonprefix of both ranges.writeln(commonPrefix("hello, world","hello, there"));// "hello, "
count(alias pred = "a == b", Range, E)(Rangehaystack, Eneedle)haystack.front,needle))));count(alias pred = "a == b", R1, R2)(R1haystack, R2needle)haystack.front,needle.front))));needle inhaystack.haystack forwhichpred(e,needle) istrue.pred defaults toequality. PerformsΟ(haystack.length) evaluations ofpred.The second overload counts the number of timesneedle was matched inhaystack.pred compares elements in each range.Throws an exception ifneedle.empty istrue, as the countof the empty range in any range would be infinite. Overlapped countsarenot considered, for examplecount("aaa", "aa") is1, not2.NoteRegardless of the overload,count will not acceptinfinite ranges forhaystack.
| pred | The predicate to compare elements. |
Rangehaystack | The range to count. |
Eneedle | The element or sub-range to count inhaystack. |
haystack.// count elements in rangeint[] a = [ 1, 2, 4, 3, 2, 5, 3, 2, 4 ];writeln(count(a, 2));// 3writeln(count!("a > b")(a, 2));// 5
import std.uni : toLower;// count range in rangewriteln(count("abcadfabf","ab"));// 2writeln(count("ababab","abab"));// 1writeln(count("ababab","abx"));// 0// fuzzy count range in rangewriteln(count!((a, b) => toLower(a) == toLower(b))("AbcAdFaBf","ab"));// 2
count(alias pred, R)(Rhaystack)haystack.front))));count(R)(Rhaystack)haystack.haystack for whichpred(e) istrue. PerformsΟ(haystack.length) evaluations ofpred.The second overload counts the number of elements in a range.If the given range has thelength property,that is returned right away, otherwiseperformsΟ(haystack.length) to walk the range.| pred | Optional predicate to find elements. |
Rhaystack | The range to count. |
haystack (for whichpred returned true).// count elements in rangeint[] a = [ 1, 2, 4, 3, 2, 5, 3, 2, 4 ];writeln(count(a));// 9// count predicate in rangewriteln(count!("a > 2")(a));// 5
countUntil(alias pred = "a == b", R, Rs...)(Rhaystack, Rsneedles)countUntil(alias pred = "a == b", R, N)(Rhaystack, Nneedle)haystack.front,needle)) : bool));countUntil(alias pred, R)(Rhaystack)haystack.front)) : bool));needles.| pred | The predicate for determining when to stop counting. |
Rhaystack | Theinput range to be counted. |
Rsneedles | Either a single element, or aforward range of elements, to be evaluated in turn against each element inhaystack under the given predicate. |
haystack before reaching an element for whichstartsWith!pred(haystack,needles) istrue. IfstartsWith!pred(haystack,needles) is nottrue for any element inhaystack, then-1 is returned. If more than one needle is provided,countUntil will wrap the result in a tuple similar toTuple!(ptrdiff_t, "steps", ptrdiff_tneedle)writeln(countUntil("hello world","world"));// 6writeln(countUntil("hello world", 'r'));// 8writeln(countUntil("hello world","programming"));// -1writeln(countUntil("日本語","本語"));// 1writeln(countUntil("日本語", '語'));// 2writeln(countUntil("日本語","五"));// -1writeln(countUntil("日本語", '五'));// -1writeln(countUntil([0, 7, 12, 22, 9], [12, 22]));// 2writeln(countUntil([0, 7, 12, 22, 9], 9));// 4writeln(countUntil!"a > b"([0, 7, 12, 22, 9], 20));// 3// supports multiple needlesauto res ="...hello".countUntil("ha","he");writeln(res.steps);// 3writeln(res.needle);// 1// returns -1 if no needle was foundres ="hello".countUntil("ha","hu");writeln(res.steps);// -1writeln(res.needle);// -1
import std.ascii : isDigit;import std.uni : isWhite;writeln(countUntil!(isWhite)("hello world"));// 5writeln(countUntil!(isDigit)("hello world"));// -1writeln(countUntil!"a > 20"([0, 7, 12, 22, 9]));// 3
endsWith(alias pred = "a == b", Range, Needles...)(RangedoesThisEnd, NeedleswithOneOfThese)endsWith(alias pred = "a == b", R1, R2)(R1doesThisEnd, R2withThis)doesThisEnd.back,withThis.back)) : bool));endsWith(alias pred = "a == b", R, E)(RdoesThisEnd, EwithThis)doesThisEnd.back,withThis)) : bool));endsWith(alias pred, R)(RdoesThisEnd)doesThisEnd.front), unaryFun!pred));| pred | The predicate to use for comparing elements between the range and the needle(s). |
RangedoesThisEnd | Thebidirectional range to check. |
NeedleswithOneOfThese | The needles to check against, which may be single elements, or bidirectional ranges of elements. |
R2withThis | The single element to check. |
withOneOfThese[0], 2 if it ends withwithOneOfThese[1], and soon.In the case when no needle parameters are given, returntrue iff back ofdoesThisStart fulfils predicatepred.import std.ascii : isAlpha;assert("abc".endsWith!(a => a.isAlpha));assert("abc".endsWith!isAlpha);assert(!"ab1".endsWith!(a => a.isAlpha));assert(!"ab1".endsWith!isAlpha);assert(!"".endsWith!(a => a.isAlpha));import std.algorithm.comparison : among;assert("abc".endsWith!(a => a.among('c', 'd') != 0));assert(!"abc".endsWith!(a => a.among('a', 'b') != 0));assert(endsWith("abc",""));assert(!endsWith("abc","b"));writeln(endsWith("abc","a", 'c'));// 2writeln(endsWith("abc","c","a"));// 1writeln(endsWith("abc","c","c"));// 1writeln(endsWith("abc","bc","c"));// 2writeln(endsWith("abc","x","c","b"));// 2writeln(endsWith("abc","x","aa","bc"));// 3writeln(endsWith("abc","x","aaa","sab"));// 0writeln(endsWith("abc","x","aaa", 'c',"sab"));// 3
find(alias pred, InputRange)(InputRangehaystack)find behaves similarly todropWhile in other languages.haystack,callfind!pred(retro(haystack)). Seestd.range.retro.Complexityfind performsΟ(walkLength(haystack)) evaluations ofpred.
| pred | The predicate to match an element. |
InputRangehaystack | Theinput range searched in. |
haystack advanced such that the front element satisfiespred. If no such element exists, returns an emptyhaystack.auto arr = [ 1, 2, 3, 4, 1 ];writeln(find!("a > 2")(arr));// [3, 4, 1]// with predicate aliasbool pred(int e) => e + 1 > 1.5;writeln(find!(pred)(arr));// arr
find(alias pred = "a == b", InputRange, Element)(InputRangehaystack, scope Elementneedle)haystack.front,needle)) : bool) && !is(typeof(binaryFun!pred(haystack.front,needle.front)) : bool));find(alias pred = "a == b", R1, R2)(R1haystack, scope R2needle)haystack.front,needle.front)) : bool));haystack are compared withneedle by using predicatepred withpred(haystack.front,needle).The predicate is passed tostd.functional.binaryFun, and can either accept astring, or any callable that can be executed viapred(element, element).haystack is aforward range,needle can be aforward range too.In this casestartsWith!pred(haystack,needle) is evaluated on each evaluation.Complexityfind performsΟ(walkLength(haystack)) evaluations ofpred. There are specializations that improve performance by taking advantage ofbidirectional orrandom access ranges (where possible).
| pred | The predicate for comparing each element with the needle, defaulting to equality"a == b". |
InputRangehaystack | Theinput range searched in. |
Elementneedle | The element searched for. |
haystack advanced such that the front element is the one searched for; that is, untilbinaryFun!pred(haystack.front,needle) istrue. If no such position exists, returns an emptyhaystack.import std.range.primitives;auto arr = [1, 2, 4, 4, 4, 4, 5, 6, 9];writeln(arr.find(4));// [4, 4, 4, 4, 5, 6, 9]writeln(arr.find(1));// arrwriteln(arr.find(9));// [9]writeln(arr.find!((e, n) => e > n)(4));// [5, 6, 9]writeln(arr.find!((e, n) => e < n)(4));// arrassert(arr.find(0).empty);assert(arr.find(10).empty);assert(arr.find(8).empty);writeln(find("hello, world", ','));// ", world"
import std.range.primitives;import std.uni : toLower;string[] s = ["Hello","world","!"];writeln(s.find!((e, n) => toLower(e) == n)("hello"));// s
import std.container : SList;import std.range.primitives : empty;import std.typecons : Tuple;assert(find("hello, world","World").empty);writeln(find("hello, world","wo"));// "world"writeln([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)];writeln(a.find!"a.x == b"([2, 3]));// [C(2, 0), C(3, 1), C(4, 0)]writeln(a[1 .. $].find!"a.x == b"([2, 3]));// [C(2, 0), C(3, 1), C(4, 0)]
find(alias pred = "a == b", Range, Needles...)(Rangehaystack, Needlesneedles)haystack,needles))));needles into ahaystack. The predicatepred is used throughout to compare elements. By default, elements arecompared for equality.| pred | The predicate to use for comparing elements. |
Rangehaystack | The target of the search. Must be an input range.If any ofneedles is a range with elements comparable toelements inhaystack, thenhaystack must be aforward rangesuch that the search can backtrack. |
Needlesneedles | One or more items to search for. Each ofneedles mustbe either comparable to one element inhaystack, or be itself aforward range with elements comparable with elements inhaystack. |
haystack positioned to match one of theneedles and also the 1-based index of the matching element inneedles (0 if none ofneedles matched, 1 ifneedles[0]matched, 2 ifneedles[1] matched...). The first needle to be foundwill be the one that matches. If multiple needles are found at thesame 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 listmatches).The relationship betweenhaystack andneedles simply meansthat one can e.g. search for individualints or arrays ofints in an array ofints. In addition, if elements areindividually comparable, searches of heterogeneous types are allowedas well: adouble[] can be searched for anint or ashort[], and conversely along can be searched for afloator adouble[]. This makes for efficient searches without the needto 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, lengthis considered to be 1.) The strategy used in searching severalsubranges at once maximizes cache usage by moving inhaystack asfew times as possible.import std.typecons : tuple;int[] a = [ 1, 4, 2, 3 ];writeln(find(a, 4));// [4, 2, 3]writeln(find(a, [1, 4]));// [1, 4, 2, 3]writeln(find(a, [1, 3], 4));// tuple([4, 2, 3], 2)// Mixed types allowed if comparablewriteln(find(a, 5, [1.2, 3.5], 2.0));// tuple([2, 3], 3)
find(RandomAccessRange, alias pred, InputRange)(RandomAccessRangehaystack, scope BoyerMooreFinder!(pred, InputRange)needle);RandomAccessRangehaystack | A random-access range with length and slicing. |
BoyerMooreFinder!(pred, InputRange)needle | ABoyerMooreFinder. |
haystack advanced such thatneedle is a prefix of it (if no such position exists, returnshaystack advanced to termination).import std.range.primitives : empty;int[] a = [ -1, 0, 1, 2, 3, 4, 5 ];int[] b = [ 1, 2, 3 ];writeln(find(a, boyerMooreFinder(b)));// [1, 2, 3, 4, 5]assert(find(b, boyerMooreFinder(a)).empty);
canFind(alias pred = "a == b")const arr = [0, 1, 2, 3];assert(canFind(arr, 2));assert(!canFind(arr, 4));// find one of several needlesassert(arr.canFind(3, 2));assert(arr.canFind(3, 2) == 2);// second needle foundwriteln(arr.canFind([1, 3], 2));// 2assert(canFind(arr, [1, 2], [2, 3]));writeln(canFind(arr, [1, 2], [2, 3]));// 1assert(canFind(arr, [1, 7], [2, 3]));writeln(canFind(arr, [1, 7], [2, 3]));// 2assert(!canFind(arr, [1, 3], [2, 4]));writeln(canFind(arr, [1, 3], [2, 4]));// 0
auto words = ["apple","beeswax","cardboard"];assert(!canFind(words,"bees"));assert(canFind!((string elem, string needle) => elem.startsWith(needle))(words,"bees"));
string s1 ="aaa111aaa";string s2 ="aaa222aaa";string s3 ="aaa333aaa";string s4 ="aaa444aaa";const hay = [s1, s2, s3, s4];assert(hay.canFind!(e => e.canFind("111","222")));
canFind(Range)(Rangehaystack)haystack))));canFind(Range, Element)(Rangehaystack, scope Elementneedle)haystack,needle))));needle can be found in range. PerformsΟ(haystack.length) evaluations ofpred.canFind(Range, Needles...)(Rangehaystack, scope Needlesneedles)haystack,needles))));haystack. If no needle is found, then0 is returned.findAdjacent(alias pred = "a == b", Range)(Ranger)r until it finds the first two adjacent elementsa,b that satisfypred(a, b). PerformsΟ(r.length)evaluations ofpred.| pred | The predicate to satisfy. |
Ranger | Aforward range to search in. |
r advanced to the first occurrence of two adjacent elements that satisfythe given predicate. If there are no such two elements, returnsr advanceduntil empty.int[] a = [ 11, 10, 10, 9, 8, 8, 7, 8, 9 ];autor =findAdjacent(a);writeln(r);// [10, 10, 9, 8, 8, 7, 8, 9]auto p =findAdjacent!("a < b")(a);writeln(p);// [7, 8, 9]
findAmong(alias pred = "a == b", InputRange, ForwardRange)(InputRangeseq, ForwardRangechoices)seq by callingseq.popFront until eitherfind!(pred)(choices,seq.front) istrue, orseq becomes empty.PerformsΟ(seq.length * choices.length) evaluations ofpred.For more information aboutpred seefind.| pred | The predicate to use for determining a match. |
InputRangeseq | Theinput range to search. |
ForwardRangechoices | Aforward range of possible choices. |
seq advanced to the first matching element, or until empty if there are nomatching elements.int[] a = [ -1, 0, 1, 2, 3, 4, 5 ];int[] b = [ 3, 1, 2 ];writeln(findAmong(a, b));// a[2 .. $]
findSkip(alias pred = "a == b", R1, R2)(ref R1haystack, R2needle)haystack.front,needle.front))));findSkip(alias pred, R1)(ref R1haystack)haystack.front), unaryFun!pred));needle inhaystack and positionshaystack right after the first occurrence ofneedle.haystack is advanced as long aspred evaluates totrue. Similarly, the haystack is positioned so aspred evaluates tofalse forhaystack.front. For more information aboutpred seefind.R1haystack | Theforward range to search in. |
R2needle | Theforward range to search for. |
| pred | Custom predicate for comparison of haystack and needle |
haystack is positioned after the end of the first occurrence ofneedle; otherwisefalse, leavinghaystack untouched. If no needle is provided, it returns the number of timespred(haystack.front) returned true.import std.range.primitives : empty;// 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);
import std.ascii : isWhite;string s =" abc";assert(findSkip!isWhite(s) && s =="abc");assert(!findSkip!isWhite(s) && s =="abc");s =" ";writeln(findSkip!isWhite(s));// 2
findSplit(alias pred = "a == b", R1, R2)(R1haystack, R2needle)findSplitBefore(alias pred = "a == b", R1, R2)(R1haystack, R2needle)findSplitAfter(alias pred = "a == b", R1, R2)(R1haystack, R2needle)needle inhaystack and thensplithaystack as follows.findSplit returns a tupleresult containingthree ranges.haystack beforeneedlehaystack that matchesneedlehaystackafter the match.needle was not found,result[0] comprehendshaystackentirely andresult[1] andresult[2] are empty.findSplitBefore returns a tupleresult containing two ranges.haystack beforeneedlehaystack starting with the match.needle was not found,result[0]comprehendshaystack entirely andresult[1] is empty.findSplitAfter returns a tupleresult containing two ranges.haystack up to and including thematchhaystack startingafter the match.needle was not found,result[0] is emptyandresult[1] ishaystack.In all cases, the concatenation of the returned ranges spans theentirehaystack.
haystack is a random-access range, all three components of the tuple havethe same type ashaystack. Otherwise,haystack must be aforward range andthe type ofresult[0] (andresult[1] forfindSplit) is the same asthe result ofstd.range.takeExactly.For more information aboutpred seefind.| pred | Predicate to compare 2 elements. |
R1haystack | The forward range to search. |
R2needle | The forward range to look for. |
haystack (see above fordetails). This sub-type ofTuple definesopCast!bool, whichreturnstrue when the separatingneedle was found andfalse otherwise.// findSplit returns a tripletif (auto split ="dlang-rocks".findSplit("-")){ writeln(split[0]);// "dlang" writeln(split[1]);// "-" writeln(split[2]);// "rocks"}elseassert(0);// findSplitBefore returns 2 rangesif (const split = [2, 3, 2, 3, 4, 1].findSplitBefore!"a > b"([2, 2])){ writeln(split[0]);// [2, 3, 2]// [3, 4] each greater than [2, 2] writeln(split[1]);// [3, 4, 1]}elseassert(0);
import std.range.primitives : empty;auto a ="Carl Sagan Memorial Station";auto r =findSplit(a,"Velikovsky");import std.typecons : isTuple;staticassert(isTuple!(typeof(r.asTuple)));staticassert(isTuple!(typeof(r)));assert(!r);writeln(r[0]);// aassert(r[1].empty);assert(r[2].empty);r =findSplit(a," ");writeln(r[0]);// "Carl"writeln(r[1]);// " "writeln(r[2]);// "Sagan Memorial Station"if (const r1 =findSplitBefore(a,"Sagan")){assert(r1); writeln(r1[0]);// "Carl " writeln(r1[1]);// "Sagan Memorial Station"}if (const r2 =findSplitAfter(a,"Sagan")){assert(r2); writeln(r2[0]);// "Carl Sagan" writeln(r2[1]);// " Memorial Station"}
import std.range : only;writeln([1, 2, 3, 4].findSplitBefore(only(3))[0]);// [1, 2]
minCount(alias pred = "a < b", Range)(Rangerange)range.front,range.front))));maxCount(alias pred = "a < b", Range)(Rangerange)range.front,range.front))));range along with its number ofoccurrences. Formally, the minimum is a valuex inrange such thatpred(a, x) isfalse for all valuesa inrange. Conversely, the maximum isa valuex inrange such thatpred(x, a) isfalse for all valuesainrange (note the swapped arguments topred).| pred | The ordering predicate to use to determine the extremum (minimum or maximum). |
Rangerange | Theinput range to count. |
LimitationsIf at least one of the arguments is NaN, the result isan unspecified value. Seestd.algorithm.searching.maxElementfor examples on how to cope with NaNs.
range.empty.import std.conv : text;import std.typecons : tuple;int[] a = [ 2, 3, 4, 1, 2, 4, 1, 1, 2 ];// Minimum is 1 and occurs 3 timeswriteln(a.minCount);// tuple(1, 3)// Maximum is 4 and occurs 2 timeswriteln(a.maxCount);// tuple(4, 2)
minElement(alias map = (a) => a, Range)(Ranger)minElement(alias map = (a) => a, Range, RangeElementType = ElementType!Range)(Ranger, RangeElementTypeseed)ComplexityO(n) Exactlyn - 1 comparisons are needed.
| map | custom accessor for the comparison key |
Ranger | range from which the minimal element will be selected |
RangeElementTypeseed | custom seed to use as initial element |
PreconditionIf a seed is not given,r must not be empty.
Note If at least one of the arguments is NaN, the result is an unspecified value.
If you want to ignore NaNs, you can usestd.algorithm.iteration.filter andstd.math.isNaN to remove them, before applying minElement. Add a suitable seed, to avoid error messages if all elements are NaNs:<range>.filter!(a=>!a.isNaN).minElement(<seed>);If you want to get NaN as a result if a NaN is present in the range, you can usestd.algorithm.iteration.fold andstd.math.isNaN:
<range>.fold!((a,b)=>a.isNaN || b.isNaN ?real.nan : a < b ? a : b);import std.range : enumerate;import std.typecons : tuple;writeln([2, 7, 1, 3].minElement);// 1// allows to get the index of an element toowriteln([5, 3, 7, 9].enumerate.minElement!"a.value");// tuple(1, 3)// any custom accessor can be passedwriteln([[0, 4], [1, 2]].minElement!"a[1]");// [1, 2]// can be seededint[] arr;writeln(arr.minElement(1));// 1
maxElement(alias map = (a) => a, Range)(Ranger)maxElement(alias map = (a) => a, Range, RangeElementType = ElementType!Range)(Ranger, RangeElementTypeseed)ComplexityO(n) Exactlyn - 1 comparisons are needed.
| map | custom accessor for the comparison key |
Ranger | range from which the maximum element will be selected |
RangeElementTypeseed | custom seed to use as initial element |
PreconditionIf a seed is not given,r must not be empty.
NoteIf at least one of the arguments is NaN, the result is an unspecified value. Seestd.algorithm.searching.minElement for examples on how to cope with NaNs.
import std.range : enumerate;import std.typecons : tuple;writeln([2, 1, 4, 3].maxElement);// 4// allows to get the index of an element toowriteln([2, 1, 4, 3].enumerate.maxElement!"a.value");// tuple(2, 4)// any custom accessor can be passedwriteln([[0, 4], [1, 2]].maxElement!"a[1]");// [0, 4]// can be seededint[] arr;writeln(arr.minElement(1));// 1
extrema(Range)(Ranger)r. Performs< 3n/2 comparisons, unlike the naive< 2n.Ranger | The range to traverse. |
writeln(extrema([5, 2, 9, 4, 1]));// [1, 9]
minPos(alias pred = "a < b", Range)(Rangerange)range.front,range.front))));maxPos(alias pred = "a < b", Range)(Rangerange)range.front,range.front))));range starting at the first occurrence ofrange'sminimum (respectively maximum) and with the same ending asrange, or theempty range ifrange itself is empty.range such thatpred(a, x) isfalse for all valuesa inrange. Conversely, the maximum is a valuex inrange such thatpred(x, a) isfalse for all valuesa inrange (notethe swapped arguments topred).These functions may be used for computing arbitrary extrema by choosingpredappropriately. For corrrect functioning,pred must be a strict partial order,i.e. transitive (ifpred(a, b) && pred(b, c) thenpred(a, c)) andirreflexive (pred(a, a) isfalse).| pred | The ordering predicate to use to determine the extremum (minimum or maximum) element. |
Rangerange | Theforward range to search. |
range, i.e. a subrange ofrange starting at the position of itssmallest (respectively largest) element and with the same ending asrange.LimitationsIf at least one of the arguments is NaN, the result isan unspecified value. Seestd.algorithm.searching.maxElementfor examples on how to cope with NaNs.
int[] a = [ 2, 3, 4, 1, 2, 4, 1, 1, 2 ];// Minimum is 1 and first occurs in position 3writeln(a.minPos);// [1, 2, 4, 1, 1, 2]// Maximum is 4 and first occurs in position 2writeln(a.maxPos);// [4, 1, 2, 4, 1, 1, 2]
minIndex(alias pred = "a < b", Range)(Rangerange)range.front,range.front))));range's minimum element.| pred | The ordering predicate to use to determine the minimum element. |
Rangerange | Theinput range to search. |
ComplexityΟ(range.length) Exactlyrange.length - 1 comparisons are needed.
range. If therange is empty, -1 is returned.LimitationsIf at least one of the arguments is NaN, the result is an unspecified value. Seestd.algorithm.searching.maxElement for examples on how to cope with NaNs.
int[] a = [2, 3, 4, 1, 2, 4, 1, 1, 2];// Minimum is 1 and first occurs in position 3writeln(a.minIndex);// 3// Get maximum index with minIndexwriteln(a.minIndex!"a > b");// 2// Range is empty, so return value is -1int[] b;writeln(b.minIndex);// -1// Works with more custom typesstruct Dog {int age; }Dog[] dogs = [Dog(10), Dog(5), Dog(15)];writeln(dogs.minIndex!"a.age < b.age");// 1
maxIndex(alias pred = "a < b", Range)(Rangerange)range.front,range.front))));range's maximum element.ComplexityΟ(range) Exactlyrange.length - 1 comparisons are needed.
| pred | The ordering predicate to use to determine the maximum element. |
Rangerange | Theinput range to search. |
range. If therange is empty, -1 is returned.LimitationsIf at least one of the arguments is NaN, the result is an unspecified value. Seestd.algorithm.searching.maxElement for examples on how to cope with NaNs.
// Maximum is 4 and first occurs in position 2int[] a = [2, 3, 4, 1, 2, 4, 1, 1, 2];writeln(a.maxIndex);// 2// Empty rangeint[] b;writeln(b.maxIndex);// -1// Works with more custom typesstruct Dog {int age; }Dog[] dogs = [Dog(10), Dog(15), Dog(5)];writeln(dogs.maxIndex!"a.age < b.age");// 1
skipOver(alias pred = (a, b) => a == b)| pred | The predicate that determines whether elements from each respective range match. Defaults to equality"a == b". |
import std.algorithm.comparison : equal;auto s1 ="Hello world";assert(!skipOver(s1,"Ha"));writeln(s1);// "Hello world"assert(skipOver(s1,"Hell") && s1 =="o world", s1);string[] r1 = ["abc","def","hij"];dstring[] r2 = ["abc"d];assert(!skipOver!((a, b) => a.equal(b))(r1, ["def"d]), r1[0]);writeln(r1);// ["abc", "def", "hij"]assert(skipOver!((a, b) => a.equal(b))(r1, r2));writeln(r1);// ["def", "hij"]
import std.ascii : isWhite;import std.range.primitives : empty;auto s2 ="\t\tvalue";auto s3 ="";auto s4 ="\t\t\t";assert(s2.skipOver!isWhite && s2 =="value");assert(!s3.skipOver!isWhite);assert(s4.skipOver!isWhite && s3.empty);
auto s ="Hello world";assert(!skipOver(s,"hello","HellO"));writeln(s);// "Hello world"// the range is skipped over the longest matching needle is skippedassert(skipOver(s,"foo","hell","Hello "));writeln(s);// "world"
import std.algorithm.comparison : equal;auto s1 ="Hello world";assert(!skipOver(s1, 'a'));writeln(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));writeln(r);// ["abc", "def", "hij"]assert(skipOver!((a, b) => a.equal(b))(r, e));writeln(r);// ["def", "hij"]auto s2 ="";assert(!s2.skipOver('a'));
import std.ascii : isWhite;import std.range.primitives : empty;alias whitespaceSkiper =skipOver!isWhite;auto s2 ="\t\tvalue";auto s3 ="";auto s4 ="\t\t\t";assert(whitespaceSkiper(s2) && s2 =="value");assert(!whitespaceSkiper(s2));assert(whitespaceSkiper(s4) && s3.empty);
skipOver(Haystack, Needles...)(ref Haystackhaystack, Needlesneedles)haystack.front,needles[0].front))) && isForwardRange!Haystack && allSatisfy!(isInputRange, Needles) && !is(CommonType!(staticMap!(ElementType, staticMap!(Unqual, Needles))) == void));skipOver(R)(ref Rr1)r1.front), unaryFun!pred));skipOver(R, Es...)(ref Rr, Eses)r.front,es[0]))));Haystackhaystack | Theforward range to move forward. |
Needlesneedles | Theinput ranges representing the prefix ofr1 to skip over. |
Eses | The element to match. |
haystack matches any range ofneedles fully orpred evaluates to true, andhaystack has been advanced to the point past this segment; otherwise false, andhaystack is left in its original position.NoteBy definition, empty ranges are matched fully and ifneedles contains an empty range,skipOver will returntrue.
startsWith(alias pred = (a, b) => a == b, Range, Needles...)(RangedoesThisStart, NeedleswithOneOfThese)startsWith(alias pred = "a == b", R1, R2)(R1doesThisStart, R2withThis)doesThisStart.front,withThis.front)) : bool));startsWith(alias pred = "a == b", R, E)(RdoesThisStart, EwithThis)doesThisStart.front,withThis)) : bool));startsWith(alias pred, R)(RdoesThisStart)doesThisStart.front), unaryFun!pred));| pred | Predicate to use in comparing the elements of the haystack and the needle(s). Mandatory if no needles are given. |
RangedoesThisStart | The input range to check. |
NeedleswithOneOfThese | The needles against which the range is to be checked, which may be individual elements or input ranges of elements. |
R2withThis | The single needle to check, which may be either a single element or an input range of elements. |
withOneOfThese[0], 2 if it starts withwithOneOfThese[1], and soon.In the case wheredoesThisStart starts with multiple of the ranges orelements inwithOneOfThese, then the shortest one matches (if there aretwo which match which are of the same length (e.g."a" and'a'), thenthe left-most of them in the argumentlist matches).In the case when no needle parameters are given, returntrue iff front ofdoesThisStart fulfils predicatepred.import std.ascii : isAlpha;assert("abc".startsWith!(a => a.isAlpha));assert("abc".startsWith!isAlpha);assert(!"1ab".startsWith!(a => a.isAlpha));assert(!"".startsWith!(a => a.isAlpha));import std.algorithm.comparison : among;assert("abc".startsWith!(a => a.among('a', 'b') != 0));assert(!"abc".startsWith!(a => a.among('b', 'c') != 0));assert(startsWith("abc",""));assert(startsWith("abc","a"));assert(!startsWith("abc","b"));writeln(startsWith("abc", 'a',"b"));// 1writeln(startsWith("abc","b","a"));// 2writeln(startsWith("abc","a","a"));// 1writeln(startsWith("abc","ab","a"));// 2writeln(startsWith("abc","x","a","b"));// 2writeln(startsWith("abc","x","aa","ab"));// 3writeln(startsWith("abc","x","aaa","sab"));// 0writeln(startsWith("abc","x","aaa","a","sab"));// 3import std.typecons : Tuple;alias C = Tuple!(int,"x",int,"y");assert(startsWith!"a.x == b"([ C(1,1), C(1,2), C(2,2) ], [1, 1]));writeln(startsWith!"a.x == b"([C(1, 1), C(2, 1), C(2, 2)], [1, 1], [1, 2], [1, 3]));// 2
OpenRight = std.typecons.Flag!"openRight".Flag;OpenRight.yes, then the interval is open to the right(last element is not included).Otherwise if set toOpenRight.no, then the interval is closed to the rightincluding the entire sentinel.until(alias pred = "a == b", Range, Sentinel)(Rangerange, Sentinelsentinel, OpenRightopenRight = Yes.openRight)until(alias pred, Range)(Rangerange, OpenRightopenRight = Yes.openRight);Until(alias pred, Range, Sentinel) if (isInputRange!Range);range until the elemente for whichpred(e,sentinel) is true.| pred | Predicate to determine when to stop. |
Rangerange | Theinput range to iterate over. |
Sentinelsentinel | The element to stop at. |
OpenRightopenRight | Determines whether the element for which the given predicate is true should be included in the resulting range (No.openRight), or not (Yes.openRight). |
import std.algorithm.comparison : equal;import std.typecons : No;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, No.openRight), [1, 2, 4, 7]));