summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas Williams <nico@cryptonector.com>2014-07-02 21:45:49 -0500
committerNicolas Williams <nico@cryptonector.com>2014-07-02 22:05:33 -0500
commit78a8419428779d0d78274d0316141ec63bfa5d15 (patch)
tree7a6ffe0120b7ec8f1f30c16993ed3d2f88f43e88
parentff9a61ead2127fc849ff3a77b63658b8fce8c5c9 (diff)
Add `while(cond; update)` (fix #314)
-rw-r--r--builtin.c5
-rw-r--r--docs/content/3.manual/manual.yml22
-rw-r--r--tests/all.test4
3 files changed, 31 insertions, 0 deletions
diff --git a/builtin.c b/builtin.c
index f42b4c94..6af99898 100644
--- a/builtin.c
+++ b/builtin.c
@@ -958,6 +958,11 @@ static const char* const jq_builtins[] = {
" def _range: "
" if (by > 0 and . < upto) or (by < 0 and . > upto) then ., ((.+by)|_range) else . end; "
" if by == 0 then init else init|_range end | select((by > 0 and . < upto) or (by < 0 and . > upto));",
+ // generic iterator/generator
+ "def while(cond; update): "
+ " def _while: "
+ " if cond then ., (update | _while) else empty end; "
+ " _while;",
};
#undef LIBM_DD
diff --git a/docs/content/3.manual/manual.yml b/docs/content/3.manual/manual.yml
index aa71bf66..e4b268af 100644
--- a/docs/content/3.manual/manual.yml
+++ b/docs/content/3.manual/manual.yml
@@ -1241,6 +1241,21 @@ sections:
input: '["a","b,c,d","e"]'
output: ['"a, b,c,d, e"']
+ - title: "`while(cond; update)`"
+ body: |
+
+ The `while(cond; update)` function allows you to repeatedly
+ apply an update to `.` until `cond` is false.
+
+ Note that `while(cond; update)` is internally defined as a jq
+ function written in jq, using only functional constructs. See
+ advanced topics below.
+
+ examples:
+ - program: '[while(.<100; .*2)]'
+ input: '1'
+ output: ['[1,2,4,8,16,32,64]']
+
- title: "`recurse(f)`, `recurse`, `recurse_down`"
body: |
@@ -1759,6 +1774,13 @@ sections:
range(0; 10; 3)'
input: 'null'
output: ['0,3,6,9']
+ - program: 'def while(cond; update):
+ def _while:
+ if cond then ., (update | _while) else empty end;
+ _while;
+ [while(.<100; .*2)]'
+ input: '1'
+ output: ['[1,2,4,8,16,32,64]']
- title: Assignment
body: |
diff --git a/tests/all.test b/tests/all.test
index c9dc900c..e50b9250 100644
--- a/tests/all.test
+++ b/tests/all.test
@@ -218,6 +218,10 @@ null
null
[0,-1,-2,-3,-4]
+[while(.<100; .*2)]
+1
+[1,2,4,8,16,32,64]
+
#
# Slices
#