summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2019-04-16 07:20:52 +0200
committerEugen Wissner <belka@caraus.de>2019-04-16 07:20:52 +0200
commitf214f3baa2f3b613f39ded5ac615a887603aa05c (patch)
tree77a23a89e8d327a015f18f4f58ac07fa1fc8e9ec /source
parentf66935f40d58e33c2882f5899186dce743bc91ad (diff)
downloadtanya-f214f3baa2f3b613f39ded5ac615a887603aa05c.tar.gz
Add algorithm.iteration.foldl
Diffstat (limited to 'source')
-rw-r--r--source/tanya/algorithm/iteration.d53
1 files changed, 53 insertions, 0 deletions
diff --git a/source/tanya/algorithm/iteration.d b/source/tanya/algorithm/iteration.d
index f759e1d..0e91c5d 100644
--- a/source/tanya/algorithm/iteration.d
+++ b/source/tanya/algorithm/iteration.d
@@ -727,3 +727,56 @@ auto singleton(E)(return ref E element)
singleChar.popFront();
assert(singleChar.empty);
}
+
+/**
+ * Accumulates all elements of a range using a function.
+ *
+ * $(D_PSYMBOL foldl) 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 foldl) accumulates from left to right.
+ *
+ * Params:
+ * F = Callable accepting the accumulator and a range element.
+ */
+template foldl(F...)
+if (F.length == 1)
+{
+ /**
+ * Params:
+ * R = Input range type.
+ * T = Type of the accumulated value.
+ * range = Input range.
+ * init = Initial value.
+ *
+ * Returns: Accumulated value.
+ */
+ T foldl(R, T)(R range, auto ref T init)
+ if (isInputRange!R && !isInfinite!R)
+ {
+ if (range.empty)
+ {
+ return init;
+ }
+ else
+ {
+ auto acc = F[0](init, range.front);
+ range.popFront;
+ return foldl(range, acc);
+ }
+ }
+}
+
+///
+@nogc nothrow pure @safe unittest
+{
+ int[3] range = [1, 2, 3];
+ const actual = foldl!((acc, x) => acc + x)(range[], 0);
+
+ assert(actual == 6);
+}