diff --git a/builtin.c b/builtin.c index f50cbca8..8926d004 100644 --- a/builtin.c +++ b/builtin.c @@ -724,6 +724,8 @@ static const char* const jq_builtins[] = { "def values: arrays, objects, booleans, numbers, strings;", "def scalars: select(. == null or . == true or . == false or type == \"number\" or type == \"string\");", "def join(x): reduce .[] as $i (\"\"; . + (if . == \"\" then $i else x + $i end));", + "def flatten: reduce .[] as $i ([]; if $i | type == \"array\" then . + ($i | flatten) else . + [$i] end);", + "def flatten(x): reduce .[] as $i ([]; if $i | type == \"array\" and x > 0 then . + ($i | flatten(x-1)) else . + [$i] end);", }; #undef LIBM_DD diff --git a/docs/content/3.manual/manual.yml b/docs/content/3.manual/manual.yml index 35396fb6..3518743d 100644 --- a/docs/content/3.manual/manual.yml +++ b/docs/content/3.manual/manual.yml @@ -796,6 +796,28 @@ sections: input: '[]' output: ["true"] + - title: "`flatten`" + body: | + + The filter `flatten` takes as input an array of nested arrays, + and produces a flat array in which all arrays inside the original + array have been recursively replaced by their values. You can pass + an argument to it to specify how many levels of nesting to flatten. + + examples: + - program: flatten + input: '[1, [2], [[3]]]' + output: ["[1, 2, 3]"] + - program: flatten(1) + input: '[1, [2], [[3]]]' + output: ["[1, 2, [3]]"] + - program: flatten + input: '[[]]' + output: ["[]"] + - program: flatten + input: '[{"foo": "bar"}, [{"foo": "baz"}]]' + output: ['[{"foo": "bar"}, {"foo": "baz"}]'] + - title: "`range`" body: | diff --git a/tests/all.test b/tests/all.test index 35293dc2..1e220cd0 100644 --- a/tests/all.test +++ b/tests/all.test @@ -846,3 +846,15 @@ map([1,2][0:.]) [.[]|nulls] [1,2,"foo",[],[3,[]],{},true,false,null] [null] + +flatten +[0, [1], [[2]], [[[3]]]] +[0, 1, 2, 3] + +flatten(2) +[0, [1], [[2]], [[[3]]]] +[0, 1, 2, [3]] + +flatten(2) +[0, [1, [2]], [1, [[3], 2]]] +[0, 1, 2, 1, [3], 2] \ No newline at end of file