diff --git a/LambdaExtension.php b/LambdaExtension.php
index a62b05f..b584f70 100644
--- a/LambdaExtension.php
+++ b/LambdaExtension.php
@@ -19,13 +19,13 @@ public function getOperators()
{
return [
[
- '=>' => [
+ '==>' => [
'precedence' => 0,
'class' => '\DPolac\TwigLambda\NodeExpression\SimpleLambda'
],
],
[
- '=>' => [
+ '==>' => [
'precedence' => 0,
'class' => '\DPolac\TwigLambda\NodeExpression\LambdaWithArguments',
'associativity' => \Twig_ExpressionParser::OPERATOR_LEFT
@@ -67,6 +67,7 @@ public function getFilters()
new \Twig_SimpleFilter('group_by', '\DPolac\TwigLambda\LambdaExtension::groupBy'),
new \Twig_SimpleFilter('sort_by', '\DPolac\TwigLambda\LambdaExtension::sortBy'),
new \Twig_SimpleFilter('count_by', '\DPolac\TwigLambda\LambdaExtension::countBy'),
+ new \Twig_SimpleFilter('unfold', '\DPolac\TwigLambda\LambdaExtension::unfold'),
];
}
@@ -292,9 +293,28 @@ public static function call($callback, array $args = [])
}
return call_user_func_array($callback, $args);
}
+
+ public static function unfold($state, $callback, array $unfolded = [])
+ {
+ if (!is_callable($callback)) {
+ throw new \InvalidArgumentException('First argument must be callable.');
+ }
+
+ while (true)
+ {
+ $retval = $callback($state);
+ if (is_null($retval))
+ break;
+
+ list ($newVal, $state) = $retval;
+ $unfolded[] = $newVal;
+ }
+
+ return $unfolded;
+ }
public function getName()
{
return 'dpolac_lambda_extension';
}
-}
\ No newline at end of file
+}
diff --git a/README.md b/README.md
index 618c537..48f7fb9 100644
--- a/README.md
+++ b/README.md
@@ -121,6 +121,22 @@ Returns array of elements that passes a test specified by lambda.
----------------------------------------------------------------
+
+### |unfold
+**Signature:** `state|unfold(lambda[, retval = []])`
+
+Given a lambda that returns an array `[value, state]` or `null`, repeatedly
+calls the function until it returns `null`, passing the new `state` on each
+call. Returns an array of the accumulated values.
+
+
+```twig
+{% do [1, 1]|unfold(=> _[1] > 1000 ? null : [ _[0] + _[1], [ _[1], _[0] + _[1]]], [1, 1]) %}
+{# Calculates the Fibonacci numbers up to and including 1597. #}
+```
+
+----------------------------------------------------------------
+
### |unique_by
**Signature:** `array|unique_by(lambda|'==='|'==')`