]> granicus.if.org Git - jq/commitdiff
Implement the 'add' builtin promised by the docs' examples.
authorStephen Dolan <mu@netsoc.tcd.ie>
Tue, 18 Sep 2012 22:32:24 +0000 (23:32 +0100)
committerStephen Dolan <mu@netsoc.tcd.ie>
Tue, 18 Sep 2012 22:32:24 +0000 (23:32 +0100)
builtin.c
docs/content/3.manual/manual.yml
testdata

index f291a95e879091e6aaef417bb69fd5148faa485d..1eee5bb51de5261338fc57c977cea0b602e78876 100644 (file)
--- a/builtin.c
+++ b/builtin.c
@@ -90,6 +90,25 @@ static void f_divide(jv input[], jv output[]) {
   }  
 }
 
+static void f_add(jv input[], jv output[]) {
+  jv array = input[0];
+  if (jv_get_kind(array) != JV_KIND_ARRAY) {
+    output[0] = jv_invalid_with_msg(jv_string_fmt("Cannot add elements of an %s",
+                                                  jv_kind_name(jv_get_kind(array))));
+  } else if (jv_array_length(jv_copy(array)) == 0) {
+    output[0] = jv_null();
+  } else {
+    jv sum = jv_array_get(jv_copy(array), 0);
+    for (int i = 1; i < jv_array_length(jv_copy(array)); i++) {
+      jv x = jv_array_get(jv_copy(array), i);
+      jv add_args[] = {jv_null(), x, sum};
+      f_plus(add_args, &sum);
+    }
+    output[0] = sum;
+  }
+  jv_free(array);
+}
+
 static void f_equal(jv input[], jv output[]) {
   jv_free(input[0]);
   output[0] = jv_bool(jv_equal(input[2], input[1]));
@@ -185,6 +204,7 @@ static struct cfunction function_list[] = {
   {f_equal, "_equal", CALL_BUILTIN_3_1},
   {f_length, "length", CALL_BUILTIN_1_1},
   {f_type, "type", CALL_BUILTIN_1_1},
+  {f_add, "add", CALL_BUILTIN_1_1},
 };
 
 static struct symbol_table cbuiltins = {function_list, sizeof(function_list)/sizeof(function_list[0])};
index 417432b49549c6783639ba57fbab6ea4c361a354..10998dceed7fbd2c3f6a9ac4ff2eb3306f343d46 100644 (file)
@@ -321,6 +321,43 @@ sections:
             input: '[[1,2], "string", {"a":2}, null]'
             output: [2, 6, 1, 0]
 
+      - title: `map(x)`
+        body: |
+
+          For any filter `x`, `map(x)` will run that filter for each
+          element of the input array, and produce the outputs a new
+          array. `map(.+1)` will increment each element of an array of numbers.
+
+          `map(x)` is equivalent to `[.[] | x]`. In fact, this is how
+          it's defined.
+
+        examples:
+          - program: 'map(.+1)'
+            input: '[1,2,3]'
+            output: ['[2,3,4]']
+
+      - title: `add`
+        body: |
+
+          The filter `add` 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 `+` operator (described above).
+
+          If the input is an empty array, `add` returns `null`.
+
+        examples:
+          - program: add
+            input: '["a","b","c"]'
+            output: ["abc"]
+          - program: add
+            input: '[1, 2, 3]'
+            output: [6]
+          - program: add
+            input: '[]'
+            output: ["null"]
+            
       - title: `tonumber`
         body: |
 
index 7357ccb27fb3ce53cef77368188439b3e75790f8..8a28997343de773025b17d94b207891f3843b150 100644 (file)
--- a/testdata
+++ b/testdata
@@ -211,6 +211,10 @@ null
 null
 [1,2,3,4]
 
+map(add)
+[[], [1,2,3], ["a","b","c"], [[3],[4,5],[6]], [{"a":1}, {"b":2}, {"a":3}]]
+[null, 6, "abc", [3,4,5,6], {"a":3, "b": 2}]
+
 #
 # User-defined functions
 # Oh god.