summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--builtin.c2
-rw-r--r--docs/content/3.manual/manual.yml32
2 files changed, 33 insertions, 1 deletions
diff --git a/builtin.c b/builtin.c
index b0c6c34c..5818a6a4 100644
--- a/builtin.c
+++ b/builtin.c
@@ -544,7 +544,7 @@ static const char* jq_builtins[] = {
"def del(f): delpaths([path(f)]);",
"def _assign(paths; value): value as $v | fold . as $obj (path(paths) as $p | $obj | setpath($p; $v));",
"def _modify(paths; update): fold . as $obj (path(paths) as $p | $obj | setpath($p; getpath($p) | update));",
-
+ "def recurse(f): ., (f | select(. != null) | recurse(f));",
};
diff --git a/docs/content/3.manual/manual.yml b/docs/content/3.manual/manual.yml
index fba7e4a7..de608210 100644
--- a/docs/content/3.manual/manual.yml
+++ b/docs/content/3.manual/manual.yml
@@ -643,6 +643,38 @@ sections:
input: '{"foo": 12, "bar":[1,2,{"barp":12, "blip":13}]}'
output: ['false']
+ - title: `recurse`
+ body: |
+
+ The `recurse` function allows you to search through a
+ recursive structure, and extract interesting data from all
+ levels. Suppose your input represents a filesystem:
+
+ {"name": "/", "children": [
+ {"name": "/bin", "children": [
+ {"name": "/bin/ls", "children": []},
+ {"name": "/bin/sh", "children": []}]},
+ {"name": "/home", "children": [
+ {"name": "/home/stephen", "children": [
+ {"name": "/home/stephen/jq", "children": []}]}]}]}
+
+ Now suppose you want to extract all of the filenames
+ present. You need to retrieve `.name`, `.children[].name`,
+ `.children[].children[].name`, and so on. You can do this
+ with:
+
+ recurse(.children[]) | .name
+
+ examples:
+ - program: 'recurse(.foo[])'
+ input: '{"foo":[{"foo": []}, {"foo":[{"foo":[]}]}]}'
+ output:
+ - '{"foo":[{"foo":[]},{"foo":[{"foo":[]}]}]}'
+ - '{"foo":[]}'
+ - '{"foo":[{"foo":[]}]}'
+ - '{"foo":[]}'
+
+
- title: "String interpolation - `\(foo)`"
body: |