diff --git a/docs/content/manual/dev/manual.yml b/docs/content/manual/dev/manual.yml index 1eb7d9b867..2ec138fc42 100644 --- a/docs/content/manual/dev/manual.yml +++ b/docs/content/manual/dev/manual.yml @@ -1300,7 +1300,7 @@ sections: input: '[1,[[],{"a":2}]]' output: ['[[0],[1,1,"a"]]'] - - title: "`add`" + - title: "`add`, `add(generator)`" body: | The filter `add` takes as input an array, and produces as @@ -1311,6 +1311,9 @@ sections: If the input is an empty array, `add` returns `null`. + `add(generator)` operates on the given generator rather than + the input. + examples: - program: add input: '["a","b","c"]' @@ -1321,6 +1324,9 @@ sections: - program: add input: '[]' output: ["null"] + - program: add(.[].a) + input: '[{"a":3}, {"a":5}, {"b":6}]' + output: ['8'] - title: "`any`, `any(condition)`, `any(generator; condition)`" body: | diff --git a/jq.1.prebuilt b/jq.1.prebuilt index 7239e87d16..151868fddf 100644 --- a/jq.1.prebuilt +++ b/jq.1.prebuilt @@ -1,5 +1,5 @@ . -.TH "JQ" "1" "May 2024" "" "" +.TH "JQ" "1" "July 2024" "" "" . .SH "NAME" \fBjq\fR \- Command\-line JSON processor @@ -1340,12 +1340,15 @@ jq \'[paths(type == "number")]\' . .IP "" 0 . -.SS "add" +.SS "add, add(generator)" The filter \fBadd\fR takes as input an array, and produces as output the elements of the array added together\. This might mean summed, concatenated or merged depending on the types of the elements of the input array \- the rules are the same as those for the \fB+\fR operator (described above)\. . .P If the input is an empty array, \fBadd\fR returns \fBnull\fR\. . +.P +\fBadd(generator)\fR operates on the given generator rather than the input\. +. .IP "" 4 . .nf @@ -1361,6 +1364,10 @@ jq \'add\' jq \'add\' [] => null + +jq \'add(\.[]\.a)\' + [{"a":3}, {"a":5}, {"b":6}] +=> 8 . .fi . diff --git a/src/builtin.jq b/src/builtin.jq index 802595bafd..aa33cd4b75 100644 --- a/src/builtin.jq +++ b/src/builtin.jq @@ -8,7 +8,8 @@ def unique: group_by(.) | map(.[0]); def unique_by(f): group_by(f) | map(.[0]); def max_by(f): _max_by_impl(map([f])); def min_by(f): _min_by_impl(map([f])); -def add: reduce .[] as $x (null; . + $x); +def add(f): reduce f as $x (null; . + $x); +def add: add(.[]); def del(f): delpaths([path(f)]); def abs: if . < 0 then - . else . end; def _assign(paths; $value): reduce path(paths) as $p (.; setpath($p; $value)); diff --git a/tests/jq.test b/tests/jq.test index 1502fbe058..d249bc1936 100644 --- a/tests/jq.test +++ b/tests/jq.test @@ -642,6 +642,19 @@ map_values(.+1) [0,1,2] [1,2,3] +[add(null), add(range(range(10))), add(empty), add(10,range(10))] +null +[null,120,null,55] + +# Real-world use case for add(empty) +.sum = add(.arr[]) +{"arr":[]} +{"arr":[],"sum":null} + +add({(.[]):1}) | keys +["a","a","b","a","d","b","d","a","d"] +["a","b","d"] + # # User-defined functions # Oh god. diff --git a/tests/man.test b/tests/man.test index 7a9cf6798c..6c5eba390a 100644 --- a/tests/man.test +++ b/tests/man.test @@ -358,6 +358,10 @@ add [] null +add(.[].a) +[{"a":3}, {"a":5}, {"b":6}] +8 + any [true, false] true