Add algorithm.iteration.foldr
This commit is contained in:
parent
73535568b7
commit
0a973b46ba
@ -779,3 +779,63 @@ if (F.length == 1)
|
|||||||
|
|
||||||
assert(actual == 6);
|
assert(actual == 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accumulates all elements of a range using a function.
|
||||||
|
*
|
||||||
|
* $(D_PSYMBOL foldr) takes a function, an input range and the initial value.
|
||||||
|
* The function takes this initial value and the first element of the range (in
|
||||||
|
* this order), puts them together and returns the result. The return
|
||||||
|
* type of the function should be the same as the type of the initial value.
|
||||||
|
* This is than repeated for all the remaining elements of the range, whereby
|
||||||
|
* the value returned by the passed function is used at the place of the
|
||||||
|
* initial value.
|
||||||
|
*
|
||||||
|
* $(D_PSYMBOL foldr) accumulates from right to left.
|
||||||
|
*
|
||||||
|
* Params:
|
||||||
|
* F = Callable accepting the accumulator and a range element.
|
||||||
|
*/
|
||||||
|
template foldr(F...)
|
||||||
|
if (F.length == 1)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Params:
|
||||||
|
* R = Bidirectional range type.
|
||||||
|
* T = Type of the accumulated value.
|
||||||
|
* range = Bidirectional range.
|
||||||
|
* init = Initial value.
|
||||||
|
*
|
||||||
|
* Returns: Accumulated value.
|
||||||
|
*/
|
||||||
|
auto foldr(R, T)(R range, auto ref T init)
|
||||||
|
if (isBidirectionalRange!R)
|
||||||
|
{
|
||||||
|
if (range.empty)
|
||||||
|
{
|
||||||
|
return init;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto acc = F[0](init, getAndPopBack(range));
|
||||||
|
return foldr(range, acc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
int[3] range = [1, 2, 3];
|
||||||
|
int[3] output;
|
||||||
|
const int[3] expected = [3, 2, 1];
|
||||||
|
|
||||||
|
alias f = (acc, x) {
|
||||||
|
acc.front = x;
|
||||||
|
acc.popFront;
|
||||||
|
return acc;
|
||||||
|
};
|
||||||
|
const actual = foldr!f(range[], output[]);
|
||||||
|
|
||||||
|
assert(output[] == expected[]);
|
||||||
|
}
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
module tanya.container.hashtable;
|
module tanya.container.hashtable;
|
||||||
|
|
||||||
|
import tanya.algorithm.iteration;
|
||||||
import tanya.algorithm.mutation;
|
import tanya.algorithm.mutation;
|
||||||
import tanya.container.array;
|
import tanya.container.array;
|
||||||
import tanya.container.entry;
|
import tanya.container.entry;
|
||||||
@ -718,12 +719,7 @@ if (isHashFunction!(hasher, Key))
|
|||||||
size_t insert(R)(scope R range)
|
size_t insert(R)(scope R range)
|
||||||
if (isForwardRange!R && is(ElementType!R == KeyValue) && !isInfinite!R)
|
if (isForwardRange!R && is(ElementType!R == KeyValue) && !isInfinite!R)
|
||||||
{
|
{
|
||||||
size_t count;
|
return foldl!((acc, x) => acc + insert(x))(range, 0U);
|
||||||
foreach (e; range)
|
|
||||||
{
|
|
||||||
count += insert(e);
|
|
||||||
}
|
|
||||||
return count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
module tanya.container.list;
|
module tanya.container.list;
|
||||||
|
|
||||||
import tanya.algorithm.comparison;
|
import tanya.algorithm.comparison;
|
||||||
|
import tanya.algorithm.iteration;
|
||||||
import tanya.container.entry;
|
import tanya.container.entry;
|
||||||
import tanya.memory.allocator;
|
import tanya.memory.allocator;
|
||||||
import tanya.memory.lifetime;
|
import tanya.memory.lifetime;
|
||||||
@ -1690,12 +1691,7 @@ struct DList(T)
|
|||||||
&& isImplicitlyConvertible!(ElementType!R, T))
|
&& isImplicitlyConvertible!(ElementType!R, T))
|
||||||
in (checkRangeBelonging(r))
|
in (checkRangeBelonging(r))
|
||||||
{
|
{
|
||||||
size_t inserted;
|
return foldl!((acc, x) => acc + insertAfter(r, x))(el, 0U);
|
||||||
foreach (e; el)
|
|
||||||
{
|
|
||||||
inserted += insertAfter(r, e);
|
|
||||||
}
|
|
||||||
return inserted;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
Loading…
Reference in New Issue
Block a user