Implements algorithms oriented mainly towards processing of
sequences. Some functions are semantic equivalents or supersets of
those found in the
. The predicate may be passed either as a
function name, a delegate name, a
name, or a
compile-time string. The string may consist of
(for binary functions). These names will NOT
interfere with other homonym symbols in user code because they are
evaluated in a different context. The default for all binary
comparison predicates is
Cheat SheetFunction Name | Description |
---|
map | Implements the homonym function (also known as transform) present
in many languages of functional flavor. The call map!(fun)(range)
returns a range of which elements are obtained by applying fun(x)
left to right for all x in range. The original ranges are
not changed. Evaluation is done lazily. The range returned by map
caches the last value such that evaluating front multiple times
does not result in multiple calls to fun.
|
BoyerMooreFinder | Finds two or more needles into a haystack. The predicate pred is used throughout to compare elements. By default, elements are
compared for equality.
|
EditOp | Encodes edit operations necessary to transform one sequence into
another. Given sequences s (source) and t (target), a
sequence of EditOp encodes the steps that need to be taken to
convert s into t. For example, if s = "cat" and "cars", the minimal sequence that transforms s into t is:
skip two characters, replace 't' with 'r', and insert an 's'. Working
with edit operations is useful in applications such as spell-checkers
(to find the closest word to a given misspelled word), approximate
searches, diff-style programs that compute the difference between
files, efficient encoding of patches, DNA sequence analysis, and
plagiarism detection. |
Group | Similarly to uniq, group iterates unique consecutive
elements of the given range. The element type is Tuple!(ElementType!R, uint) because it includes the count of
equivalent elements seen. Equivalence of elements is assessed by using
the predicate pred, by default "a == b".
|
NWayUnion | Computes the union of multiple sets. The input sets are passed as a
range of ranges and each is assumed to be sorted by less. Computation is done lazily, one union element at a time. The
complexity of one popFront operation is O(log(ror.length)). However, the length of ror decreases as ranges
in it are exhausted, so the complexity of a full pass through NWayUnion is dependent on the distribution of the lengths of ranges
contained within ror. If all ranges have the same length n
(worst case scenario), the complexity of a full pass through NWayUnion is O(n * ror.length * log(ror.length)), i.e., log(ror.length) times worse than just spanning all ranges in
turn. The output comes sorted (unstably) by less.
|
OpenRight | Interval option specifier for until (below) and others. |
SetDifference | Lazily computes the difference of r1 and r2. The two ranges
are assumed to be sorted by less. The element types of the two
ranges must have a common type.
|
SetIntersection | Lazily computes the intersection of two or more input ranges rs. The ranges are assumed to be sorted by less. The element
types of all ranges must have a common type.
|
SetSymmetricDifference | Lazily computes the symmetric difference of r1 and r2,
i.e. the elements that are present in exactly one of r1 and r2. The two ranges are assumed to be sorted by less, and the
output is also sorted by less. The element types of the two
ranges must have a common type.
|
SetUnion | Lazily computes the union of two or more ranges rs. The ranges
are assumed to be sorted by less. Elements in the output are not
unique; the length of the output is the sum of the lengths of the
inputs. (The length member is offered if all ranges also have
length.) The element types of all ranges must have a common type.
|
SortOutput | Specifies whether the output of certain algorithm is desired in sorted
format. |
Splitter | Splits a range using an element as a separator. This can be used with
any range type, but is most popular with string types.
|
Splitter | Splits a range using another range as a separator. This can be used
with any range type, but is most popular with string types. |
SwapStrategy | Defines the swapping strategy for algorithms that need to swap
elements in a range (such as partition and sort). The strategy
concerns the swapping of elements that are not the core concern of the
algorithm. For example, consider an algorithm that sorts [ "abc",
"b", "aBc" ] according to toupper(a) < toupper(b). That
algorithm might choose to swap the two equivalent strings "abc"
and "aBc". That does not affect the sorting since both [
"abc", "aBc", "b" ] and [ "aBc", "abc", "b" ] are valid
outcomes.
|
Uniq | Iterates unique consecutive elements of the given range (functionality
akin to the uniq system
utility). Equivalence of elements is assessed by using the predicate
pred, by default "a == b". If the given range is
bidirectional, uniq also yields a bidirectional range.
|
Until | Lazily iterates range until value sentinel is found, at
which point it stops.
|
balancedParens | 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.
|
boyerMooreFinder | Finds two or more needles into a haystack. The predicate pred is used throughout to compare elements. By default, elements are
compared for equality.
|
bringToFront | The bringToFront function has considerable flexibility and
usefulness. It can rotate elements in one buffer left or right, swap
buffers of equal length, and even move elements across disjoint
buffers of different types and different lengths.
|
canFind | Returns true if and only if a value v satisfying the
predicate pred can be found in the forward range range. Performs O(r.length) evaluations of pred. |
canFind | Returns true if and only if value can be found in range. Performs O(r.length) evaluations of pred. |
completeSort | Sorts the random-access range chain(lhs, rhs) according to
predicate less. The left-hand side of the range lhs is
assumed to be already sorted; rhs is assumed to be unsorted. The
exact strategy chosen depends on the relative sizes of lhs and
rhs. Performs O(lhs.length + rhs.length * log(rhs.length))
(best case) to O((lhs.length + rhs.length) * log(lhs.length +
rhs.length)) (worst-case) evaluations of swap.
|
copy | Copies the content of source into target and returns the
remaining (unfilled) part of target. See also STL's copy. If a behavior similar to
STL's copy_backward is
needed, use copy(retro(source), retro(target)). See also std.range.retro.
|
count | Counts the number of elements x in r for which pred(x)
is true. Performs O(r.length) evaluations of pred.
|
count | Counts the number of elements x in r for which pred(x,
value) is true. pred defaults to equality. Performs O(r.length) evaluations of pred.
|
endsWith | Checks whether doesThisEnd starts with one of the individual
elements withOneOfThese according to pred.
|
endsWith | The reciprocal of startsWith.
|
equal | Returns true if and only if the two ranges compare equal element
for element, according to binary predicate pred. The ranges may
have different element types, as long as pred(a, b) evaluates to
bool for a in r1 and b in r2. Performs
O(min(r1.length, r2.length)) evaluations of pred. See also
STL's equal.
|
fill | Fills range with a pattern copied from filler. The length of
range does not have to be a multiple of the length of filler. If filler is empty, an exception is thrown.
|
fill | Fills a range with a value.
|
filter | Implements the homonym function present in various programming
languages of functional flavor. The call filter!(fun)(range)
returns a new range only containing elements x in r for
which predicate(x) is true.
|
find | Advances the input range haystack by calling haystack.popFront
until either pred(haystack.front), or haystack.empty. Performs O(haystack.length) evaluations of pred. See also STL's find_if.
|
find | Finds a forward range in another. Elements are compared for
equality. Performs O(walkLength(haystack) * walkLength(needle))
comparisons in the worst case. Specializations taking advantage of
bidirectional or random access (where present) may accelerate search
depending on the statistics of the two ranges' content.
|
find | Finds two or more needles into a haystack. The predicate pred is used throughout to compare elements. By default, elements are
compared for equality.
|
find | Finds an individual element in an input range. Elements of haystack are compared with needle by using predicate pred. Performs O(walkLength(haystack)) evaluations of pred. See also STL's find.
|
findAdjacent | Advances r until it finds the first two adjacent elements a,
b that satisfy pred(a, b). Performs O(r.length)
evaluations of pred. See also STL's adjacent_find.
|
findAmong | Advances seq by calling seq.popFront until either find!(pred)(choices, seq.front) is true, or seq becomes
empty. Performs O(seq.length * choices.length) evaluations of
pred. See also STL's
find_first_of.
|
group | Similarly to uniq, group iterates unique consecutive
elements of the given range. The element type is Tuple!(ElementType!R, uint) because it includes the count of
equivalent elements seen. Equivalence of elements is assessed by using
the predicate pred, by default "a == b".
|
indexOf | If haystack supports slicing, returns the smallest number n
such that haystack[n .. $].startsWith!pred(needle). Oherwise,
returns the smallest n such that after n calls to haystack.popFront, haystack.startsWith!pred(needle). If no such
number could be found, return -1. |
initializeAll | Initializes all elements of a range with their .init
value. Assumes that the range does not currently contain meaningful
content.
|
isPartitioned | Returns true if r is partitioned according to predicate pred.
|
isSorted | Checks whether a forward range is sorted according to the comparison
operation less. Performs O(r.length) evaluations of less.
|
largestPartialIntersection | Given a range of sorted forward ranges ror, copies to tgt
the elements that are common to most ranges, along with their number
of occurrences. All ranges in ror are assumed to be sorted by less. Only the most frequent tgt.length elements are returned.
|
largestPartialIntersectionWeighted | Similar to largestPartialIntersection, but associates a weight
with each distinct element in the intersection.
|
levenshteinDistance | Returns the Levenshtein
distance between s and t. The Levenshtein distance computes
the minimal amount of edit operations necessary to transform s
into t. Performs O(s.length * t.length) evaluations of equals and occupies O(s.length * t.length) storage.
|
levenshteinDistanceAndPath | Returns the Levenshtein distance and the edit path between s and
t.
|
makeIndex | Computes an index for r based on the comparison less. The
index is a sorted array of pointers or indices into the original
range. This technique is similar to sorting, but it is more flexible
because (1) it allows "sorting" of immutable collections, (2) allows
binary search even if the original collection does not offer random
access, (3) allows multiple indexes, each on a different predicate,
and (4) may be faster when dealing with large objects. However, using
an index may also be slower under certain circumstances due to the
extra indirection, and is always larger than a sorting-based solution
because it needs space for the index in addition to the original
collection. The complexity is the same as sort's.
|
makeIndex | Computes an index for r based on the comparison less. The
index is a sorted array of pointers or indices into the original
range. This technique is similar to sorting, but it is more flexible
because (1) it allows "sorting" of immutable collections, (2) allows
binary search even if the original collection does not offer random
access, (3) allows multiple indexes, each on a different predicate,
and (4) may be faster when dealing with large objects. However, using
an index may also be slower under certain circumstances due to the
extra indirection, and is always larger than a sorting-based solution
because it needs space for the index in addition to the original
collection. The complexity is the same as sort's.
|
max | Returns the maximum of the passed-in values. The type of the result is
computed by using std.traits.CommonType.
|
min | Returns the minimum of the passed-in values. The type of the result is
computed by using std.traits.CommonType. |
minCount | 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).
|
minPos | 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 counting the maximum or any other ordering
predicate (that's why maxPos is not provided).
|
mismatch | Sequentially compares elements in r1 and r2 in lockstep, and
stops at the first mismatch (according to pred, by default
equality). Returns a tuple with the reduced ranges that start with the
two mismatched values. Performs O(min(r1.length, r2.length))
evaluations of pred. See also STL's mismatch.
|
move | Moves source into target via a destructive
copy. Specifically: - If hasAliasing!T is true (see
std.traits.hasAliasing), then the representation of source
is bitwise copied into target and then source = T.init is
evaluated.
- Otherwise, target = source is evaluated.
See
also std.contracts.pointsTo.
|
move | Moves source into target via a destructive
copy. Specifically: - If hasAliasing!T is true (see
std.traits.hasAliasing), then the representation of source
is bitwise copied into target and then source = T.init is
evaluated.
- Otherwise, target = source is evaluated.
See
also std.contracts.pointsTo.
|
moveAll | For each element a in src and each element b in tgt in lockstep in increasing order, calls move(a, b). Returns
the leftover portion of tgt. Throws an exeption if there is not
enough room in tgt to acommodate all of src.
|
moveSome | For each element a in src and each element b in tgt in lockstep in increasing order, calls move(a, b). Stops
when either src or tgt have been exhausted. Returns the
leftover portions of the two ranges. |
nWayUnion | Computes the union of multiple sets. The input sets are passed as a
range of ranges and each is assumed to be sorted by less. Computation is done lazily, one union element at a time. The
complexity of one popFront operation is O(log(ror.length)). However, the length of ror decreases as ranges
in it are exhausted, so the complexity of a full pass through NWayUnion is dependent on the distribution of the lengths of ranges
contained within ror. If all ranges have the same length n
(worst case scenario), the complexity of a full pass through NWayUnion is O(n * ror.length * log(ror.length)), i.e., log(ror.length) times worse than just spanning all ranges in
turn. The output comes sorted (unstably) by less.
|
partialSort | Reorders the random-access range r such that the range r[0
.. mid] is the same as if the entire r were sorted, and leaves
the range r[mid .. r.length] in no particular order. Performs
O(r.length * log(mid)) evaluations of pred. The
implementation simply calls topN!(less, ss)(r, n) and then sort!(less, ss)(r[0 .. n]).
|
partition | Partitions a range in two using pred as a
predicate. Specifically, reorders the range r = [left,
right) using swap such that all elements i for
which pred(i) is true come before all elements j for
which pred(j) returns false.
|
reduce | Implements the homonym function (also known as accumulate, compress, inject, or foldl) present in various programming
languages of functional flavor. The call reduce!(fun)(seed,
range) first assigns seed to an internal variable result,
also called the accumulator. Then, for each element x in range, result = fun(result, x) gets evaluated. Finally, result is returned. The one-argument version reduce!(fun)(range)
works similarly, but it uses the first element of the range as the
seed (the range must be non-empty).
|
remove | Eliminates elements at given offsets from range and returns the
shortened range. In the simplest call, one element is removed.
|
remove | Reduces the length of the bidirectional range range by only
keeping elements that satisfy pred. If , elements are moved from the right end of the
range over the elements to eliminate. If s = SwapStrategy.stable
(the default), elements are moved progressively to front such that
their relative order is preserved. Returns the tail portion of the
range that was moved.
|
reverse | Reverses r in-place. Performs r.length evaluations of swap. See also STL's reverse.
|
schwartzSort | Sorts a range using an algorithm akin to the Schwartzian transform, also
known as the decorate-sort-undecorate pattern in Python and Lisp. (Not
to be confused with the other
Schwartz.) This function is helpful when the sort comparison includes
an expensive computation. The complexity is the same as that of the
corresponding sort, but schwartzSort evaluates transform only r.length times (less than half when compared to
regular sorting). The usage can be best illustrated with an example.
|
setDifference | Lazily computes the difference of r1 and r2. The two ranges
are assumed to be sorted by less. The element types of the two
ranges must have a common type.
|
setIntersection | Lazily computes the intersection of two or more input ranges rs. The ranges are assumed to be sorted by less. The element
types of all ranges must have a common type.
|
setSymmetricDifference | Lazily computes the symmetric difference of r1 and r2,
i.e. the elements that are present in exactly one of r1 and r2. The two ranges are assumed to be sorted by less, and the
output is also sorted by less. The element types of the two
ranges must have a common type.
|
setUnion | Lazily computes the union of two or more ranges rs. The ranges
are assumed to be sorted by less. Elements in the output are not
unique; the length of the output is the sum of the lengths of the
inputs. (The length member is offered if all ranges also have
length.) The element types of all ranges must have a common type.
|
skipOver | If startsWith(r1, r2), consume the corresponding elements off r1 and return true. Otherwise, leave r1 unchanged and
return false. |
skipOver | Checks whether a range starts with an element, and if so, consume that
element off r and return true. Otherwise, leave r
unchanged and return false. |
sort | Sorts a random-access range according to predicate less. Performs
O(r.length * log(r.length)) (if unstable) or O(r.length *
log(r.length) * log(r.length)) (if stable) evaluations of less
and swap. See also STL's sort
and stable_sort.
|
splitter | Splits a range using an element as a separator. This can be used with
any range type, but is most popular with string types.
|
startsWith | If the range doesThisStart starts with any of the withOneOfThese ranges or elements, returns 1 if it starts with withOneOfThese[0], 2 if it starts with withOneOfThese[1], and so
on. If no match, returns 0.
|
startsWith | If the range doesThisStart starts with any of the withOneOfThese ranges or elements, returns 1 if it starts with withOneOfThese[0], 2 if it starts with withOneOfThese[1], and so
on. If no match, returns 0.
|
startsWith | If the range doesThisStart starts with any of the withOneOfThese ranges or elements, returns 1 if it starts with withOneOfThese[0], 2 if it starts with withOneOfThese[1], and so
on. If no match, returns 0.
|
swap | Swaps lhs and rhs. See also std.exception.pointsTo.
|
swapRanges | Swaps all elements of r1 with successive elements in r2.
Returns a tuple containing the remainder portions of r1 and r2 that were not swapped (one of them will be empty). The ranges may
be of different types but must have the same element type and support
swapping.
|
topN | Reorders the range r using swap such that r[nth] refers
to the element that would fall there if the range were fully
sorted. In addition, it also partitions r such that all elements
e1 from r[0] to r[nth] satisfy !less(r[nth], e1),
and all elements e2 from r[nth] to r[r.length] satisfy
!less(e2, r[nth]). Effectively, it finds the nth smallest
(according to less) elements in r. Performs O(r.length) (if unstable) or O(r.length * log(r.length)) (if
stable) evaluations of less and swap. See also STL's nth_element.
|
topN | Stores the smallest elements of the two ranges in the left-hand range. |
topNCopy | Copies the top n elements of the input range source into the
random-access range target, where n =
target.length. Elements of source are not touched. If sorted is true, the target is sorted. Otherwise, the target
respects the heap property.
|
uninitializedFill | Fills a range with a value. Assumes that the range does not currently
contain meaningful content. This is of interest for structs that
define copy constructors (for all other types, fill and
uninitializedFill are equivalent).
|
uniq | Iterates unique consecutive elements of the given range (functionality
akin to the uniq system
utility). Equivalence of elements is assessed by using the predicate
pred, by default "a == b". If the given range is
bidirectional, uniq also yields a bidirectional range.
|
until | Lazily iterates range until value sentinel is found, at
which point it stops.
|
until | Lazily iterates range until value sentinel is found, at
which point it stops.
|
- Implements the homonym function (also known as transform) present
in many languages of functional flavor. The call map!(fun)(range)
returns a range of which elements are obtained by applying fun(x)
left to right for all x in range. The original ranges are
not changed. Evaluation is done lazily. The range returned by map
caches the last value such that evaluating front multiple times
does not result in multiple calls to fun.
Briefly:
map!"2 * a"([1, 2, 3]) lazily returns a range with the numbers 2, 4, 6.
Example:
int[] arr1 = [ 1, 2, 3, 4 ];
int[] arr2 = [ 5, 6 ];
auto squares = map!("a * a")(chain(arr1, arr2));
assert(equal(squares, [ 1, 4, 9, 16, 25, 36 ]));
Multiple functions can be passed to map. In that case, the
element type of map is a tuple containing one element for each
function.
Example:
auto arr1 = [ 1, 2, 3, 4 ];
foreach (e; map!("a + a", "a * a")(arr1))
{
writeln(e[0], " ", e[1]);
}
You may alias map with some function(s) to a symbol and use it
separately:
alias map!(to!string) stringize;
assert(equal(stringize([ 1, 2, 3, 4 ]), [ "1", "2", "3", "4" ]));
See Also:
Iteration
- Implements the homonym function (also known as accumulate, compress, inject, or foldl) present in various programming
languages of functional flavor. The call reduce!(fun)(seed,
range) first assigns seed to an internal variable result,
also called the accumulator. Then, for each element x in range, result = fun(result, x) gets evaluated. Finally, result is returned. The one-argument version reduce!(fun)(range)
works similarly, but it uses the first element of the range as the
seed (the range must be non-empty).
Many aggregate range operations turn out to be solved with reduce
quickly and easily. The example below illustrates reduce's
remarkable power and flexibility.
Example:
int[] arr = [ 1, 2, 3, 4, 5 ];
auto sum = reduce!("a + b")(0, arr);
assert(sum == 15);
auto largest = reduce!(max)(arr);
assert(largest == 5);
auto odds = reduce!("a + (b & 1)")(0, arr);
assert(odds == 3);
auto ssquares = reduce!("a + b * b")(0, arr);
assert(ssquares == 55);
int[] a = [ 3, 4 ];
int[] b = [ 100 ];
auto r = reduce!("a + b")(chain(a, b));
assert(r == 107);
double[] c = [ 2.5, 3.0 ];
auto r1 = reduce!("a + b")(chain(a, b, c));
assert(r1 == 112.5);
Multiple functions:
Sometimes it is very useful to
compute multiple aggregates in one pass. One advantage is that the
computation is faster because the looping overhead is shared. That's
why reduce accepts multiple functions. If two or more functions
are passed, reduce returns a std.typecons.Tuple object with
one member per passed-in function. The number of seeds must be
correspondingly increased.
Example:
double[] a = [ 3.0, 4, 7, 11, 3, 2, 5 ];
auto r = reduce!(min, max)(a);
assert(r[0] == 2); assert(r[1] == 11);
r = reduce!("a + b", "a + b * b")(tuple(0.0, 0.0), a);
assert(r[0] == 35); assert(r[1] == 233); auto avg = r[0] / a.length;
auto stdev = sqrt(r[1] / a.length - avg * avg);
void
fill(Range, Value)(Range
range, Value
filler);
- Fills a range with a value.
Example:
int[] a = [ 1, 2, 3, 4 ];
fill(a, 5);
assert(a == [ 5, 5, 5, 5 ]);
void
fill(Range1, Range2)(Range1
range, Range2
filler);
- Fills range with a pattern copied from filler. The length of
range does not have to be a multiple of the length of filler. If filler is empty, an exception is thrown.
Example:
int[] a = [ 1, 2, 3, 4, 5 ];
int[] b = [ 8, 9 ];
fill(a, b);
assert(a == [ 8, 9, 8, 9, 8 ]);
void
uninitializedFill(Range, Value)(Range
range, Value
filler);
- Fills a range with a value. Assumes that the range does not currently
contain meaningful content. This is of interest for structs that
define copy constructors (for all other types, fill and
uninitializedFill are equivalent).
Example:
struct S { ... }
S[] s = (cast(S*) malloc(5 * S.sizeof))[0 .. 5];
uninitializedFill(s, 42);
assert(s == [ 42, 42, 42, 42, 42 ]);
void
initializeAll(Range)(Range
range);
- Initializes all elements of a range with their .init
value. Assumes that the range does not currently contain meaningful
content.
Example:
struct S { ... }
S[] s = (cast(S*) malloc(5 * S.sizeof))[0 .. 5];
initialize(s);
assert(s == [ 0, 0, 0, 0, 0 ]);
template
filter(alias pred)
- Implements the homonym function present in various programming
languages of functional flavor. The call filter!(fun)(range)
returns a new range only containing elements x in r for
which predicate(x) is true.
Example:
int[] arr = [ 1, 2, 3, 4, 5 ];
auto small = filter!("a < 3")(arr);
assert(small == [ 1, 2 ]);
int[] a = [ 3, -2, 400 ];
int[] b = [ 100, -101, 102 ];
auto r = filter!("a > 0")(chain(a, b));
assert(equal(r, [ 3, 400, 100, 102 ]));
double[] c = [ 2.5, 3.0 ];
auto r1 = filter!("cast(int) a != a")(chain(c, a, b));
assert(r1 == [ 2.5 ]);
void
move(T)(ref T
source, ref T
target);
T
move(T)(ref T
src);
- Moves source into target via a destructive
copy. Specifically:
- If hasAliasing!T is true (see
std.traits.hasAliasing), then the representation of source
is bitwise copied into target and then source = T.init is
evaluated.
- Otherwise, target = source is evaluated.
See
also std.contracts.pointsTo.
Preconditions:
&source == &target || !pointsTo(source, source)
Range2
moveAll(Range1, Range2)(Range1
src, Range2
tgt);
- For each element a in src and each element b in tgt in lockstep in increasing order, calls move(a, b). Returns
the leftover portion of tgt. Throws an exeption if there is not
enough room in tgt to acommodate all of src.
Preconditions:
walkLength(src) >= walkLength(tgt)
Tuple!(Range1,Range2)
moveSome(Range1, Range2)(Range1
src, Range2
tgt);
- For each element a in src and each element b in tgt in lockstep in increasing order, calls move(a, b). Stops
when either src or tgt have been exhausted. Returns the
leftover portions of the two ranges.
void
swap(T)(ref T
a, ref T
b);
- Swaps lhs and rhs. See also std.exception.pointsTo.
Preconditions:
!pointsTo(lhs, lhs) && !pointsTo(lhs, rhs) && !pointsTo(rhs, lhs)
&& !pointsTo(rhs, rhs)
struct
Splitter(Range,Separator) if (is(typeof(ElementType!(Range).init == Separator.init)) && hasSlicing!(Range));
Splitter!(Range,Separator)
splitter(Range, Separator)(Range
r, Separator
s);
- Splits a range using an element as a separator. This can be used with
any range type, but is most popular with string types.
Two adjacent separators are considered to surround an empty element in
the split range.
If the empty range is given, the result is a range with one empty
element. If a range with one separator is given, the result is a range
with two empty elements.
Example:
assert(equal(splitter("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, 0), w));
a = null;
assert(equal(splitter(a, 0), [ (int[]).init ]));
a = [ 0 ];
assert(equal(splitter(a, 0), [ (int[]).init, (int[]).init ]));
a = [ 0, 1 ];
assert(equal(splitter(a, 0), [ [], [1] ]));
struct
Splitter(Range,Separator) if (is(typeof(Range.init.front == Separator.init.front)));
- Splits a range using another range as a separator. This can be used
with any range type, but is most popular with string types.
struct
Uniq(alias pred,R);
Uniq!(pred,Range)
uniq(alias pred = "a == b", Range)(Range
r);
- Iterates unique consecutive elements of the given range (functionality
akin to the uniq system
utility). Equivalence of elements is assessed by using the predicate
pred, by default "a == b". If the given range is
bidirectional, uniq also yields a bidirectional range.
Example:
int[] arr = [ 1, 2, 2, 2, 2, 3, 4, 4, 4, 5 ];
assert(equal(uniq(arr), [ 1, 2, 3, 4, 5 ][]));
struct
Group(alias pred,R) if (isInputRange!(R));
Group!(pred,Range)
group(alias pred = "a == b", Range)(Range
r);
- Similarly to uniq, group iterates unique consecutive
elements of the given range. The element type is Tuple!(ElementType!R, uint) because it includes the count of
equivalent elements seen. Equivalence of elements is assessed by using
the predicate pred, by default "a == b".
Group is an input range if R is an input range, and a
forward range in all other cases.
Example:
int[] arr = [ 1, 2, 2, 2, 2, 3, 4, 4, 4, 5 ];
assert(equal(group(arr), [ tuple(1, 1u), tuple(2, 4u), tuple(3, 1u),
tuple(4, 3u), tuple(5, 1u) ][]));
R
find(alias pred = "a == b", R, E)(R
haystack, E
needle);
- Finds an individual element in an input range. Elements of haystack are compared with needle by using predicate pred. Performs O(walkLength(haystack)) evaluations of pred. See also STL's find.
To find the last occurence of needle in haystack, call find(retro(haystack), needle). See also std.range.retro.
Parameters:
haystack |
The range searched in. |
needle |
The element searched for. |
Constraints:
isInputRange!R && is(typeof(binaryFun!pred(haystack.front, needle)
: bool))
Returns:
haystack advanced such that binaryFun!pred(haystack.front,
needle) is true (if no such position exists, returns haystack after exhaustion).
Example:
assert(find("hello, world", ',') == ", world");
assert(find([1, 2, 3, 5], 4) == []);
assert(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); assert(!find(a, 2).empty);
string[] s = [ "Hello", "world", "!" ];
assert(!find!("tolower(a) == b")(s, "hello").empty);
R1
find(alias pred = "a == b", R1, R2)(R1
haystack, R2
needle);
- Finds a forward range in another. Elements are compared for
equality. Performs O(walkLength(haystack) * walkLength(needle))
comparisons in the worst case. Specializations taking advantage of
bidirectional or random access (where present) may accelerate search
depending on the statistics of the two ranges' content.
Parameters:
haystack |
The range searched in. |
needle |
The range searched for. |
Constraints:
isForwardRange!R1 && isForwardRange!R2 &&
is(typeof(binaryFun!pred(haystack.front, needle.front) : bool))
Returns:
haystack advanced such that needle is a prefix of it (if no
such position exists, returns haystack advanced to termination).
assert(find("hello, world", "World").empty);
assert(find("hello, world", "wo") == "world");
assert(find([1, 2, 3, 4], SList!(2, 3)[]) == [2, 3, 4]);
Tuple!(Range,size_t)
find(alias pred = "a == b", Range, Ranges...)(Range
haystack, Ranges
needles);
struct
BoyerMooreFinder(alias pred,Range);
BoyerMooreFinder!(binaryFun!(pred),Range)
boyerMooreFinder(alias pred = "a == b", Range)(Range
needle);
- 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:
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. |
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 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.
Example:
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));
assert(find(a, 5, [ 1.2, 3.5 ], 2.0, [ 1 ]) == tuple([ 2, 3 ], 3));
The complexity of the search is O(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.
Range
find(alias pred, Range)(Range
haystack);
- Advances the input range haystack by calling haystack.popFront
until either pred(haystack.front), or haystack.empty. Performs O(haystack.length) evaluations of pred. See also STL's find_if.
To find the last element of a bidirectional haystack satisfying
pred, call find!(pred)(retro(haystack)). See also std.range.retro.
Example:
auto arr = [ 1, 2, 3, 4, 1 ];
assert(find!("a > 2")(arr) == [ 3, 4, 1 ]);
bool pred(int x) { return x + 1 > 1.5; }
assert(find!(pred)(arr) == arr);
int
indexOf(alias pred = "a == b", R1, R2)(R1
haystack, R2
needle);
- If haystack supports slicing, returns the smallest number n
such that haystack[n .. $].startsWith!pred(needle). Oherwise,
returns the smallest n such that after n calls to haystack.popFront, haystack.startsWith!pred(needle). If no such
number could be found, return -1.
- Interval option specifier for until (below) and others.
- Interval is closed to the right (last element included)
- Interval is open to the right (last element is not included)
struct
Until(alias pred,Range,Sentinel) if (isInputRange!(Range));
Until!(pred,Range,Sentinel)
until(alias pred = "a == b", Range, Sentinel)(Range
range, Sentinel
sentinel, OpenRight
openRight = OpenRight.yes);
Until!(pred,Range,void)
until(alias pred, Range)(Range
range, OpenRight
openRight = OpenRight.yes);
- Lazily iterates range until value sentinel is found, at
which point it stops.
Example:
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][]));
uint
startsWith(alias pred = "a == b", Range, Ranges...)(Range
doesThisStart, Ranges
withOneOfThese);
bool
startsWith(alias pred = "a == b", R1, R2)(R1
doesThisStart, R2
withThis);
bool
startsWith(alias pred = "a == b", R, E)(R
doesThisStart, E
withThis);
- If the range doesThisStart starts with any of the withOneOfThese ranges or elements, returns 1 if it starts with withOneOfThese[0], 2 if it starts with withOneOfThese[1], and so
on. If no match, returns 0.
Example:
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", "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);
bool
skipOver(alias pred = "a == b", R1, R2)(ref R1
r1, R2
r2);
- If startsWith(r1, r2), consume the corresponding elements off r1 and return true. Otherwise, leave r1 unchanged and
return false.
bool
skipOver(alias pred = "a == b", R, E)(ref R
r, E
e);
- Checks whether a range starts with an element, and if so, consume that
element off r and return true. Otherwise, leave r
unchanged and return false.
uint
endsWith(alias pred = "a == b", Range, Ranges...)(Range
doesThisEnd, Ranges
withOneOfThese);
- The reciprocal of startsWith.
Example:
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", "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);
uint
endsWith(alias pred = "a == b", Range, Elements...)(Range
doesThisEnd, Elements
withOneOfThese);
- Checks whether doesThisEnd starts with one of the individual
elements withOneOfThese according to pred.
Example:
assert(endsWith("abc", 'x', 'c', 'a') == 2);
Range
findAdjacent(alias pred = "a == b", Range)(Range
r);
- Advances r until it finds the first two adjacent elements a,
b that satisfy pred(a, b). Performs O(r.length)
evaluations of pred. See also STL's adjacent_find.
Example:
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 ]);
p = findAdjacent!("a < b")(a);
assert(p == [ 7, 8, 9 ]);
Range1
findAmong(alias pred = "a == b", Range1, Range2)(Range1
seq, Range2
choices);
- Advances seq by calling seq.popFront until either find!(pred)(choices, seq.front) is true, or seq becomes
empty. Performs O(seq.length * choices.length) evaluations of
pred. See also STL's
find_first_of.
Example:
int[] a = [ -1, 0, 1, 2, 3, 4, 5 ];
int[] b = [ 3, 1, 2 ];
assert(findAmong(a, b) == a[2 .. $]);
size_t
count(alias pred = "a == b", Range, E)(Range
r, E
value);
- Counts the number of elements x in r for which pred(x,
value) is true. pred defaults to equality. Performs O(r.length) evaluations of pred.
Example:
int[] a = [ 1, 2, 4, 3, 2, 5, 3, 2, 4 ];
assert(count(a, 2) == 3);
assert(count!("a > b")(a, 2) == 5);
size_t
count(alias pred, Range)(Range
r);
- Counts the number of elements x in r for which pred(x)
is true. Performs O(r.length) evaluations of pred.
Example:
int[] a = [ 1, 2, 4, 3, 2, 5, 3, 2, 4 ];
assert(count!("a > 1")(a) == 8);
bool
balancedParens(Range, E)(Range
r, E
lPar, E
rPar, size_t
maxNestingLevel = size_t.max);
- 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.
Example:
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, '(', ')', 1));
s = "1 + (2 * 3 + 1) / (2 - 5)";
assert(balancedParens(s, '(', ')', 1));
bool
equal(alias pred = "a == b", Range1, Range2)(Range1
r1, Range2
r2);
- Returns true if and only if the two ranges compare equal element
for element, according to binary predicate pred. The ranges may
have different element types, as long as pred(a, b) evaluates to
bool for a in r1 and b in r2. Performs
O(min(r1.length, r2.length)) evaluations of pred. See also
STL's equal.
Example:
int[] a = [ 1, 2, 4, 3 ];
assert(!equal(a, a[1..$]));
assert(equal(a, a));
double[] b = [ 1., 2, 4, 3];
assert(!equal(a, b[1..$]));
assert(equal(a, b));
double[] c = [ 1.005, 2, 4, 3];
assert(equal!(approxEqual)(b, c));
MinType!(T1,T2,T)
min(T1, T2, T...)(T1
a, T2
b, T
xs);
- Returns the minimum of the passed-in values. The type of the result is
computed by using std.traits.CommonType.
MaxType!(T1,T2,T)
max(T1, T2, T...)(T1
a, T2
b, T
xs);
- Returns the maximum of the passed-in values. The type of the result is
computed by using std.traits.CommonType.
Example:
int a = 5;
short b = 6;
double c = 2;
auto d = max(a, b);
assert(is(typeof(d) == int));
assert(d == 6);
auto e = min(a, b, c);
assert(is(typeof(e) == double));
assert(e == 2);
Tuple!(ElementType!(Range),size_t)
minCount(alias pred = "a < b", Range)(Range
range);
- 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).
Example:
int[] a = [ 2, 3, 4, 1, 2, 4, 1, 1, 2 ];
assert(minCount(a) == tuple(1, 3));
assert(minCount!("a > b")(a) == tuple(4, 2));
Range
minPos(alias pred = "a < b", Range)(Range
range);
- 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 counting the maximum or any other ordering
predicate (that's why maxPos is not provided).
Example:
int[] a = [ 2, 3, 4, 1, 2, 4, 1, 1, 2 ];
assert(minPos(a) == [ 1, 2, 4, 1, 1, 2 ]);
assert(minPos!("a > b")(a) == [ 4, 1, 2, 4, 1, 1, 2 ]);
Tuple!(Range1,Range2)
mismatch(alias pred = "a == b", Range1, Range2)(Range1
r1, Range2
r2);
- Sequentially compares elements in r1 and r2 in lockstep, and
stops at the first mismatch (according to pred, by default
equality). Returns a tuple with the reduced ranges that start with the
two mismatched values. Performs O(min(r1.length, r2.length))
evaluations of pred. See also STL's mismatch.
Example:
int[] x = [ 1, 5, 2, 7, 4, 3 ];
double[] y = [ 1., 5, 2, 7.3, 4, 8 ];
auto m = mismatch(x, y);
assert(m[0] == x[3 .. $]);
assert(m[1] == y[3 .. $]);
- Encodes edit operations necessary to transform one sequence into
another. Given sequences s (source) and t (target), a
sequence of EditOp encodes the steps that need to be taken to
convert s into t. For example, if s = "cat" and "cars", the minimal sequence that transforms s into t is:
skip two characters, replace 't' with 'r', and insert an 's'. Working
with edit operations is useful in applications such as spell-checkers
(to find the closest word to a given misspelled word), approximate
searches, diff-style programs that compute the difference between
files, efficient encoding of patches, DNA sequence analysis, and
plagiarism detection.
- Current items are equal; no editing is necessary.
- Substitute current item in target with current item in source.
- Insert current item from the source into the target.
- Remove current item from the target.
size_t
levenshteinDistance(alias equals = "a == b", Range1, Range2)(Range1
s, Range2
t);
- Returns the Levenshtein
distance between s and t. The Levenshtein distance computes
the minimal amount of edit operations necessary to transform s
into t. Performs O(s.length * t.length) evaluations of equals and occupies O(s.length * t.length) storage.
Example:
assert(levenshteinDistance("cat", "rat") == 1);
assert(levenshteinDistance("parks", "spark") == 2);
assert(levenshteinDistance("kitten", "sitting") == 3);
assert(levenshteinDistance!("toupper(a) == toupper(b)")
("parks", "SPARK") == 2);
Tuple!(size_t,EditOp[])
levenshteinDistanceAndPath(alias equals = "a == b", Range1, Range2)(Range1
s, Range2
t);
- Returns the Levenshtein distance and the edit path between s and
t.
Example:
string a = "Saturday", b = "Sunday";
auto p = levenshteinDistanceAndPath(a, b);
assert(p[0] == 3);
assert(equal(p[1], "nrrnsnnn"));
Range2
copy(Range1, Range2)(Range1
source, Range2
target);
- Copies the content of source into target and returns the
remaining (unfilled) part of target. See also STL's copy. If a behavior similar to
STL's copy_backward is
needed, use copy(retro(source), retro(target)). See also std.range.retro.
Example:
int[] a = [ 1, 5 ];
int[] b = [ 9, 8 ];
int[] c = new int[a.length + b.length + 10];
auto d = copy(b, copy(a, c));
assert(c[0 .. a.length + b.length] == a ~ b);
assert(d.length == 10);
As long as the target range elements support assignment from source
range elements, different types of ranges are accepted.
Example:
float[] a = [ 1.0f, 5 ];
double[] b = new double[a.length];
auto d = copy(a, b);
To copy at most n elements from range a to range b, you
may want to use copy(take(a, n), b). To copy those elements from
range a that satisfy predicate pred to range b, you may
want to use copy(filter!(pred)(a), b).
Example:
int[] a = [ 1, 5, 8, 9, 10, 1, 2, 0 ];
auto b = new int[a.length];
auto c = copy(filter!("(a & 1) == 1")(a), b);
assert(b[0 .. $ - c.length] == [ 1, 5, 9, 1 ]);
Tuple!(Range1,Range2)
swapRanges(Range1, Range2)(Range1
r1, Range2
r2);
- Swaps all elements of r1 with successive elements in r2.
Returns a tuple containing the remainder portions of r1 and r2 that were not swapped (one of them will be empty). The ranges may
be of different types but must have the same element type and support
swapping.
Example:
int[] a = [ 100, 101, 102, 103 ];
int[] b = [ 0, 1, 2, 3 ];
auto c = swapRanges(a[1 .. 3], b[2 .. 4]);
assert(c[0].empty && c[1].empty);
assert(a == [ 100, 2, 3, 103 ]);
assert(b == [ 0, 1, 101, 102 ]);
void
reverse(Range)(Range
r);
- Reverses r in-place. Performs r.length evaluations of swap. See also STL's reverse.
Example:
int[] arr = [ 1, 2, 3 ];
reverse(arr);
assert(arr == [ 3, 2, 1 ]);
size_t
bringToFront(Range1, Range2)(Range1
front, Range2
back);
- The bringToFront function has considerable flexibility and
usefulness. It can rotate elements in one buffer left or right, swap
buffers of equal length, and even move elements across disjoint
buffers of different types and different lengths.
bringToFront takes two ranges front and back, which may
be of different types. Considering the concatenation of front and
back one unified range, bringToFront rotates that unified
range such that all elements in back are brought to the beginning
of the unified range. The relative ordering of elements in front
and back, respectively, remains unchanged.
The simplest use of bringToFront is for rotating elements in a
buffer. For example:
auto arr = [4, 5, 6, 7, 1, 2, 3];
bringToFront(arr[0 .. 4], arr[4 .. $]);
assert(arr == [ 1, 2, 3, 4, 5, 6, 7 ]);
The front range may actually "step over" the back
range. This is very useful with forward ranges that cannot compute
comfortably right-bounded subranges like arr[0 .. 4] above. In
the example below, r2 is a right subrange of r1.
auto list = SList!(int)(4, 5, 6, 7, 1, 2, 3);
auto r1 = list[];
auto r2 = list[]; popFrontN(r2, 4);
assert(equal(r2, [ 1, 2, 3 ]));
bringToFront(r1, r2);
assert(equal(list[], [ 1, 2, 3, 4, 5, 6, 7 ]));
Elements can be swapped across ranges of different types:
auto list = SList!(int)(4, 5, 6, 7);
auto vec = [ 1, 2, 3 ];
bringToFront(list[], vec);
assert(equal(list[], [ 1, 2, 3, 4 ]));
assert(equal(vec, [ 5, 6, 7 ]));
Performs O(max(front.length, back.length)) evaluations of swap. See also STL's rotate.
Preconditions:
Either front and back are disjoint, or back is
reachable from front and front is not reachable from back.
Returns:
The number of elements brought to the front, i.e., the length of back.
- Defines the swapping strategy for algorithms that need to swap
elements in a range (such as partition and sort). The strategy
concerns the swapping of elements that are not the core concern of the
algorithm. For example, consider an algorithm that sorts [ "abc",
"b", "aBc" ] according to toupper(a) < toupper(b). That
algorithm might choose to swap the two equivalent strings "abc"
and "aBc". That does not affect the sorting since both [
"abc", "aBc", "b" ] and [ "aBc", "abc", "b" ] are valid
outcomes.
Some situations require that the algorithm must NOT ever change the
relative ordering of equivalent elements (in the example above, only
[ "abc", "aBc", "b" ] would be the correct result). Such
algorithms are called stable. If the ordering algorithm may swap
equivalent elements discretionarily, the ordering is called unstable.
Yet another class of algorithms may choose an intermediate tradeoff by
being stable only on a well-defined subrange of the range. There is no
established terminology for such behavior; this library calls it semistable.
Generally, the stable ordering strategy may be more costly in
time and/or space than the other two because it imposes additional
constraints. Similarly, semistable may be costlier than unstable. As (semi-)stability is not needed very often, the ordering
algorithms in this module parameterized by SwapStrategy all
choose SwapStrategy.unstable as the default.
- Allows freely swapping of elements as long as the output
satisfies the algorithm's requirements.
- In algorithms partitioning ranges in two, preserve relative
ordering of elements only to the left of the partition point.
- Preserve the relative ordering of elements to the largest
extent allowed by the algorithm's requirements.
Range
remove(SwapStrategy s = SwapStrategy.stable, Range, Offset...)(Range
range, Offset
offset);
- Eliminates elements at given offsets from range and returns the
shortened range. In the simplest call, one element is removed.
int[] a = [ 3, 5, 7, 8 ];
assert(remove(a, 1) == [ 3, 7, 8 ]);
assert(a == [ 3, 7, 8, 8 ]);
In the case above the element at offset 1 is removed and remove returns the range smaller by one element. The original array
has remained of the same length because all functions in std.algorithm only change content, not topology. The value
8 is repeated because std.algorithm.move was invoked to move
elements around and on integers move simply copies the source to
the destination. To replace a with the effect of the removal,
simply assign a = remove(a, 1). The slice will be rebound to the
shorter array and the operation completes with maximal efficiency.
Multiple indices can be passed into remove. In that case,
elements at the respective indices are all removed. The indices must
be passed in increasing order, otherwise an exception occurs.
int[] a = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
assert(remove(a, 1, 3, 5) ==
[ 0, 2, 4, 6, 7, 8, 9, 10 ]);
(Note how all indices refer to slots in the original array, not
in the array as it is being progressively shortened.) Finally, any
combination of integral offsets and tuples composed of two integral
offsets can be passed in.
int[] a = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
assert(remove(a, 1, tuple(3, 5), 9) == [ 0, 2, 6, 7, 8, 10 ]);
In this case, the slots at positions 1, 3, 4, and 9 are removed from
the array. The tuple passes in a range closed to the left and open to
the right (consistent with built-in slices), e.g. tuple(3, 5)
means indices 3 and 4 but not 5.
If the need is to remove some elements in the range but the order of
the remaining elements does not have to be preserved, you may want to
pass SwapStrategy.unstable to remove.
int[] a = [ 0, 1, 2, 3 ];
assert(remove!(SwapStrategy.unstable)(a, 1) == [ 0, 3, 2 ]);
In the case above, the element at slot 1 is removed, but replaced
with the last element of the range. Taking advantage of the relaxation
of the stability requirement, remove moved elements from the end
of the array over the slots to be removed. This way there is less data
movement to be done which improves the execution time of the function.
The function remove works on any forward range. The moving
strategy is (listed from fastest to slowest): - If s ==
SwapStrategy.unstable && isRandomAccessRange!Range &&
hasLength!Range, then elements are moved from the end of the range
into the slots to be filled. In this case, the absolute minimum of
moves is performed.
- Otherwise, if s ==
SwapStrategy.unstable && isBidirectionalRange!Range &&
hasLength!Range, then elements are still moved from the end of the
range, but time is spent on advancing between slots by repeated calls
to range.popFront.
- Otherwise, elements are moved incrementally
towards the front of range; a given element is never moved
several times, but more elements are moved than in the previous
cases.
Range
remove(alias pred, SwapStrategy s = SwapStrategy.stable, Range)(Range
range);
- Reduces the length of the bidirectional range range by only
keeping elements that satisfy pred. If , elements are moved from the right end of the
range over the elements to eliminate. If s = SwapStrategy.stable
(the default), elements are moved progressively to front such that
their relative order is preserved. Returns the tail portion of the
range that was moved.
Example:
int[] a = [ 1, 2, 3, 2, 3, 4, 5, 2, 5, 6 ];
assert(a[0 .. $ - remove!("a == 2")(a).length] == [ 1, 3, 3, 4, 5, 5, 6 ]);
Range
partition(alias predicate, SwapStrategy ss = SwapStrategy.unstable, Range)(Range
r);
- Partitions a range in two using pred as a
predicate. Specifically, reorders the range r = [left,
right) using swap such that all elements i for
which pred(i) is true come before all elements j for
which pred(j) returns false.
Performs O(r.length) (if unstable or semistable) or O(r.length * log(r.length)) (if stable) evaluations of less and swap. The unstable version computes the minimum possible evaluations
of swap (roughly half of those performed by the semistable
version).
See also STL's partition and
stable_partition.
Returns:
The right part of r after partitioning.
If ss == SwapStrategy.stable, partition preserves the
relative ordering of all elements a, b in r for which
pred(a) == pred(b). If ss == SwapStrategy.semistable, partition preserves the relative ordering of all elements a, b in the left part of r for which pred(a) == pred(b).
Example:
auto Arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
auto arr = Arr.dup;
static bool even(int a) { return (a & 1) == 0; }
auto r = partition!(even)(arr);
assert(r == arr[5 .. $]);
assert(count!(even)(arr[0 .. 5]) == 5);
assert(find!(even)(r).empty);
arr[] = Arr[];
r = partition!(q{(a & 1) == 0})(arr);
assert(r == arr[5 .. $]);
arr[] = Arr[];
r = partition!(q{(a & 1) == 0}, SwapStrategy.stable)(arr);
assert(arr == [2, 4, 6, 8, 10, 1, 3, 5, 7, 9] && r == arr[5 .. $]);
arr[] = Arr[];
int x = 3;
bool fun(int a) { return a > x; }
r = partition!(fun, SwapStrategy.semistable)(arr);
assert(arr == [4, 5, 6, 7, 8, 9, 10, 2, 3, 1] && r == arr[7 .. $]);
bool
isPartitioned(alias pred, Range)(Range
r);
- Returns true if r is partitioned according to predicate pred.
Example:
int[] r = [ 1, 3, 5, 7, 8, 2, 4, ];
assert(isPartitioned!("a & 1")(r));
void
topN(alias less = "a < b", SwapStrategy ss = SwapStrategy.unstable, Range)(Range
r, size_t
nth);
- Reorders the range r using swap such that r[nth] refers
to the element that would fall there if the range were fully
sorted. In addition, it also partitions r such that all elements
e1 from r[0] to r[nth] satisfy !less(r[nth], e1),
and all elements e2 from r[nth] to r[r.length] satisfy
!less(e2, r[nth]). Effectively, it finds the nth smallest
(according to less) elements in r. Performs O(r.length) (if unstable) or O(r.length * log(r.length)) (if
stable) evaluations of less and swap. See also STL's nth_element.
Example:
int[] v = [ 25, 7, 9, 2, 0, 5, 21 ];
auto n = 4;
topN!(less)(v, n);
assert(v[n] == 9);
topN!("a < b")(v, n);
assert(v[n] == 9);
BUGS:
Stable topN has not been implemented yet.
void
topN(alias less = "a < b", SwapStrategy ss = SwapStrategy.unstable, Range1, Range2)(Range1
r1, Range2
r2);
- Stores the smallest elements of the two ranges in the left-hand range.
SortedRange!(Range,less)
sort(alias less = "a < b", SwapStrategy ss = SwapStrategy.unstable, Range)(Range
r);
- Sorts a random-access range according to predicate less. Performs
O(r.length * log(r.length)) (if unstable) or O(r.length *
log(r.length) * log(r.length)) (if stable) evaluations of less
and swap. See also STL's sort
and stable_sort.
Example:
int[] array = [ 1, 2, 3, 4 ];
sort!("a > b")(array);
assert(array == [ 4, 3, 2, 1 ]);
sort(array);
assert(array == [ 1, 2, 3, 4 ]);
bool myComp(int x, int y) { return x > y; }
sort!(myComp)(array);
assert(array == [ 4, 3, 2, 1 ]);
string[] words = [ "aBc", "a", "abc", "b", "ABC", "c" ];
sort!("toupper(a) < toupper(b)", SwapStrategy.stable)(words);
assert(words == [ "a", "aBc", "abc", "ABC", "b", "c" ]);
void
schwartzSort(alias transform, alias less = "a < b", SwapStrategy ss = SwapStrategy.unstable, Range)(Range
r);
- Sorts a range using an algorithm akin to the Schwartzian transform, also
known as the decorate-sort-undecorate pattern in Python and Lisp. (Not
to be confused with the other
Schwartz.) This function is helpful when the sort comparison includes
an expensive computation. The complexity is the same as that of the
corresponding sort, but schwartzSort evaluates transform only r.length times (less than half when compared to
regular sorting). The usage can be best illustrated with an example.
Example:
uint hashFun(string) { ... expensive computation ... }
string[] array = ...;
sort!("hashFun(a) < hashFun(b)")(array);
schwartzSort!(hashFun, "a < b")(array);
The schwartzSort function might require less temporary data and
be faster than the Perl idiom or the decorate-sort-undecorate idiom
present in Python and Lisp. This is because sorting is done in-place
and only minimal extra data (one array of transformed elements) is
created.
To check whether an array was sorted and benefit of the speedup of
Schwartz sorting, a function schwartzIsSorted is not provided
because the effect can be achieved by calling isSorted!(less)(map!(transform)(r)).
void
partialSort(alias less = "a < b", SwapStrategy ss = SwapStrategy.unstable, Range)(Range
r, size_t
n);
- Reorders the random-access range r such that the range r[0
.. mid] is the same as if the entire r were sorted, and leaves
the range r[mid .. r.length] in no particular order. Performs
O(r.length * log(mid)) evaluations of pred. The
implementation simply calls topN!(less, ss)(r, n) and then sort!(less, ss)(r[0 .. n]).
Example:
int[] a = [ 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 ];
partialSort(a, 5);
assert(a[0 .. 5] == [ 0, 1, 2, 3, 4 ]);
void
completeSort(alias less = "a < b", SwapStrategy ss = SwapStrategy.unstable, Range1, Range2)(SortedRange!(Range1,less)
lhs, Range2
rhs);
- Sorts the random-access range chain(lhs, rhs) according to
predicate less. The left-hand side of the range lhs is
assumed to be already sorted; rhs is assumed to be unsorted. The
exact strategy chosen depends on the relative sizes of lhs and
rhs. Performs O(lhs.length + rhs.length * log(rhs.length))
(best case) to O((lhs.length + rhs.length) * log(lhs.length +
rhs.length)) (worst-case) evaluations of swap.
Example:
int[] a = [ 1, 2, 3 ];
int[] b = [ 4, 0, 6, 5 ];
completeSort(assumeSorted(a), b);
assert(a == [ 0, 1, 2 ]);
assert(b == [ 3, 4, 5, 6 ]);
bool
isSorted(alias less = "a < b", Range)(Range
r);
- Checks whether a forward range is sorted according to the comparison
operation less. Performs O(r.length) evaluations of less.
Example:
int[] arr = [4, 3, 2, 1];
assert(!isSorted(arr));
sort(arr);
assert(isSorted(arr));
sort!("a > b")(arr);
assert(isSorted!("a > b")(arr));
void
makeIndex(alias less = "a < b", SwapStrategy ss = SwapStrategy.unstable, Range, RangeIndex)(Range
r, RangeIndex
index);
void
makeIndex(alias less = "a < b", SwapStrategy ss = SwapStrategy.unstable, Range, RangeIndex)(Range
r, RangeIndex
index);
- Computes an index for r based on the comparison less. The
index is a sorted array of pointers or indices into the original
range. This technique is similar to sorting, but it is more flexible
because (1) it allows "sorting" of immutable collections, (2) allows
binary search even if the original collection does not offer random
access, (3) allows multiple indexes, each on a different predicate,
and (4) may be faster when dealing with large objects. However, using
an index may also be slower under certain circumstances due to the
extra indirection, and is always larger than a sorting-based solution
because it needs space for the index in addition to the original
collection. The complexity is the same as sort's.
makeIndex overwrites its second argument with the result, but
never reallocates it. If the second argument's length is less than
that of the range indexed, an exception is thrown.
The first overload of makeIndex writes to a range containing
pointers, and the second writes to a range containing offsets. The
first overload requires Range to be a forward range, and the
latter requires it to be a random-access range.
Example:
immutable(int[]) arr = [ 2, 3, 1, 5, 0 ];
auto index1 = new immutable(int)*[arr.length];
makeIndex!("a < b")(arr, index1);
assert(isSorted!("*a < *b")(index1));
auto index2 = new size_t[arr.length];
makeIndex!("a < b")(arr, index2);
assert(isSorted!
((size_t a, size_t b){ return arr[a] < arr[b];})
(index2));
- Specifies whether the output of certain algorithm is desired in sorted
format.
- Don't sort output
- Sort output
bool
canFind(alias pred = "a == b", Range, V)(Range
range, V
value);
- Returns true if and only if value can be found in range. Performs O(r.length) evaluations of pred.
bool
canFind(alias pred, Range)(Range
range);
- Returns true if and only if a value v satisfying the
predicate pred can be found in the forward range range. Performs O(r.length) evaluations of pred.
TRange
topNCopy(alias less = "a < b", SRange, TRange)(SRange
source, TRange
target, SortOutput
sorted = SortOutput.no);
- Copies the top n elements of the input range source into the
random-access range target, where n =
target.length. Elements of source are not touched. If sorted is true, the target is sorted. Otherwise, the target
respects the heap property.
Example:
int[] a = [ 10, 16, 2, 3, 1, 5, 0 ];
int[] b = new int[3];
topNCopy(a, b, true);
assert(b == [ 0, 1, 2 ]);
struct
SetUnion(alias less = "a < b",Rs...) if (allSatisfy!(isInputRange,Rs));
SetUnion!(less,Rs)
setUnion(alias less = "a < b", Rs...)(Rs
rs);
- Lazily computes the union of two or more ranges rs. The ranges
are assumed to be sorted by less. Elements in the output are not
unique; the length of the output is the sum of the lengths of the
inputs. (The length member is offered if all ranges also have
length.) The element types of all ranges must have a common type.
Example:
int[] a = [ 1, 2, 4, 5, 7, 9 ];
int[] b = [ 0, 1, 2, 4, 7, 8 ];
int[] c = [ 10 ];
assert(setUnion(a, b).length == a.length + b.length);
assert(equal(setUnion(a, b), [0, 1, 1, 2, 2, 4, 4, 5, 7, 7, 8, 9][]));
assert(equal(setUnion(a, c, b),
[0, 1, 1, 2, 2, 4, 4, 5, 7, 7, 8, 9, 10][]));
struct
SetIntersection(alias less = "a < b",Rs...) if (allSatisfy!(isInputRange,Rs));
SetIntersection!(less,Rs)
setIntersection(alias less = "a < b", Rs...)(Rs
ranges);
- Lazily computes the intersection of two or more input ranges rs. The ranges are assumed to be sorted by less. The element
types of all ranges must have a common type.
Example:
int[] a = [ 1, 2, 4, 5, 7, 9 ];
int[] b = [ 0, 1, 2, 4, 7, 8 ];
int[] c = [ 0, 1, 4, 5, 7, 8 ];
assert(equal(setIntersection(a, a), a));
assert(equal(setIntersection(a, b), [1, 2, 4, 7][]));
assert(equal(setIntersection(a, b, c), [1, 4, 7][]));
struct
SetDifference(alias less = "a < b",R1,R2) if (isInputRange!(R1) && isInputRange!(R2));
SetDifference!(less,R1,R2)
setDifference(alias less = "a < b", R1, R2)(R1
r1, R2
r2);
- Lazily computes the difference of r1 and r2. The two ranges
are assumed to be sorted by less. The element types of the two
ranges must have a common type.
Example:
int[] a = [ 1, 2, 4, 5, 7, 9 ];
int[] b = [ 0, 1, 2, 4, 7, 8 ];
assert(equal(setDifference(a, b), [5, 9][]));
struct
SetSymmetricDifference(alias less = "a < b",R1,R2) if (isInputRange!(R1) && isInputRange!(R2));
SetSymmetricDifference!(less,R1,R2)
setSymmetricDifference(alias less = "a < b", R1, R2)(R1
r1, R2
r2);
- Lazily computes the symmetric difference of r1 and r2,
i.e. the elements that are present in exactly one of r1 and r2. The two ranges are assumed to be sorted by less, and the
output is also sorted by less. The element types of the two
ranges must have a common type.
Example:
int[] a = [ 1, 2, 4, 5, 7, 9 ];
int[] b = [ 0, 1, 2, 4, 7, 8 ];
assert(equal(setSymmetricDifference(a, b), [0, 5, 8, 9][]));
struct
NWayUnion(alias less,RangeOfRanges);
NWayUnion!(less,RangeOfRanges)
nWayUnion(alias less = "a < b", RangeOfRanges)(RangeOfRanges
ror);
- Computes the union of multiple sets. The input sets are passed as a
range of ranges and each is assumed to be sorted by less. Computation is done lazily, one union element at a time. The
complexity of one popFront operation is O(log(ror.length)). However, the length of ror decreases as ranges
in it are exhausted, so the complexity of a full pass through NWayUnion is dependent on the distribution of the lengths of ranges
contained within ror. If all ranges have the same length n
(worst case scenario), the complexity of a full pass through NWayUnion is O(n * ror.length * log(ror.length)), i.e., log(ror.length) times worse than just spanning all ranges in
turn. The output comes sorted (unstably) by less.
Warning:
Because NWayUnion does not allocate extra memory, it
will leave ror modified. Namely, NWayUnion assumes ownership
of ror and discretionarily swaps and advances elements of it. If
you want ror to preserve its contents after the call, you may
want to pass a duplicate to NWayUnion (and perhaps cache the
duplicate in between calls).
Example:
double[][] a =
[
[ 1, 4, 7, 8 ],
[ 1, 7 ],
[ 1, 7, 8],
[ 4 ],
[ 7 ],
];
auto witness = [
1, 1, 1, 4, 4, 7, 7, 7, 7, 8, 8
];
assert(equal(nWayUnion(a), witness[]));
void
largestPartialIntersection(alias less = "a < b", RangeOfRanges, Range)(RangeOfRanges
ror, Range
tgt, SortOutput
sorted = SortOutput.no);
- Given a range of sorted forward ranges ror, copies to tgt
the elements that are common to most ranges, along with their number
of occurrences. All ranges in ror are assumed to be sorted by less. Only the most frequent tgt.length elements are returned.
Example:
double[][] a =
[
[ 1, 4, 7, 8 ],
[ 1, 7 ],
[ 1, 7, 8],
[ 4 ],
[ 7 ],
];
auto b = new Tuple!(double, uint)[1];
largestPartialIntersection(a, b);
assert(b[0] == tuple(7.0, 4u));
7.0 is the correct answer because it occurs in 4 out of the
5 inputs, more than any other number. The second member of the
resulting tuple is indeed 4 (recording the number of occurrences
of 7.0). If more of the top-frequent numbers are needed, just
create a larger tgt range. In the axample above, creating b
with length 2 yields tuple(1.0, 3u) in the second position.
The function largestPartialIntersection is useful for
e.g. searching an inverted index for the documents most
likely to contain some terms of interest. The complexity of the search
is O(n * log(tgt.length)), where n is the sum of lengths of
all input ranges. This approach is faster than keeping an associative
array of the occurrences and then selecting its top items, and also
requires less memory (largestPartialIntersection builds its
result directly in tgt and requires no extra memory).
Warning:
Because largestPartialIntersection does not allocate
extra memory, it will leave ror modified. Namely, largestPartialIntersection assumes ownership of ror and
discretionarily swaps and advances elements of it. If you want ror to preserve its contents after the call, you may want to pass a
duplicate to largestPartialIntersection (and perhaps cache the
duplicate in between calls).
void
largestPartialIntersectionWeighted(alias less = "a < b", RangeOfRanges, Range, WeightsAA)(RangeOfRanges
ror, Range
tgt, WeightsAA
weights, SortOutput
sorted = SortOutput.no);
- Similar to largestPartialIntersection, but associates a weight
with each distinct element in the intersection.
Example:
double[][] a =
[
[ 1, 4, 7, 8 ],
[ 1, 7 ],
[ 1, 7, 8],
[ 4 ],
[ 7 ],
];
auto b = new Tuple!(double, uint)[1];
double[double] weights = [ 1:1.2, 4:2.3, 7:1.1, 8:1.1 ];
largestPartialIntersectionWeighted(a, b, weights);
assert(b[0] == tuple(4.0, 2u));
The correct answer in this case is 4.0, which, although only
appears two times, has a total weight 4.6 (three times its weight
2.3). The value 7 is weighted with 1.1 and occurs four
times for a total weight 4.4.