]> granicus.if.org Git - jq/commitdiff
Add the "has" function. Closes #74.
authorStephen Dolan <mu@netsoc.tcd.ie>
Mon, 6 May 2013 12:46:16 +0000 (13:46 +0100)
committerStephen Dolan <mu@netsoc.tcd.ie>
Mon, 6 May 2013 12:46:54 +0000 (13:46 +0100)
builtin.c
docs/content/3.manual/manual.yml
jv_aux.c
jv_aux.h

index b9c60b8380c6942f66895433ab827eede83a56bb..39570188d1d55deae6d90032a3b0b6cfa6e32542 100644 (file)
--- a/builtin.c
+++ b/builtin.c
@@ -480,6 +480,7 @@ static const struct cfunction function_list[] = {
   {(cfunction_ptr)jv_setpath, "setpath", 3}, // FIXME typechecking
   {(cfunction_ptr)jv_getpath, "getpath", 2},
   {(cfunction_ptr)jv_delpaths, "delpaths", 2},
+  {(cfunction_ptr)jv_has, "has", 2},
   {(cfunction_ptr)f_equal, "_equal", 3},
   {(cfunction_ptr)f_notequal, "_notequal", 3},
   {(cfunction_ptr)f_less, "_less", 3},
index 6f80b78b9dba71370d68aea1bef5860feab8b7b9..7b490659954d7e93de8335c4b76aa66d7c096b98 100644 (file)
@@ -453,6 +453,25 @@ sections:
             input: '[42,3,35]'
             output: ['[0,1,2]']
 
+      - title: `has`
+        body: |
+          
+          The builtin function `has` returns whether the input object
+          has the given key, or the input array has an element at the
+          given index.
+
+          `has($key)` has the same effect as checking whether `$key`
+          is a member of the array returned by `keys`, although `has`
+          will be faster.
+
+        examples:
+          - program: 'map(has("foo"))'
+            input: '[{"foo": 42}, {}]'
+            output: ['[true, false]']
+          - program: 'map(has(2))'
+            input: '[[0,1], ["a","b","c"]]'
+            output: ['[false, true]']
+
       - title: `select`
         body: |
           
index 2c33491da7429e60efeea4f9309758943b2fe8b3..1f40cc4b32616662cd8464548c7ed47f54fac30b 100644 (file)
--- a/jv_aux.c
+++ b/jv_aux.c
@@ -60,6 +60,34 @@ jv jv_set(jv t, jv k, jv v) {
   return t;
 }
 
+jv jv_has(jv t, jv k) {
+  assert(jv_is_valid(t));
+  assert(jv_is_valid(k));
+  jv ret;
+  if (jv_get_kind(t) == JV_KIND_NULL) {
+    jv_free(t);
+    jv_free(k);
+    ret = jv_false();
+  } else if (jv_get_kind(t) == JV_KIND_OBJECT &&
+             jv_get_kind(k) == JV_KIND_STRING) {
+    jv elem = jv_object_get(t, k);
+    ret = jv_bool(jv_is_valid(elem));
+    jv_free(elem);
+  } else if (jv_get_kind(t) == JV_KIND_ARRAY &&
+             jv_get_kind(k) == JV_KIND_NUMBER) {
+    jv elem = jv_array_get(t, (int)jv_number_value(k));
+    ret = jv_bool(jv_is_valid(elem));
+    jv_free(elem);
+  } else {
+    ret = jv_invalid_with_msg(jv_string_fmt("Cannot check whether %s has a %s key",
+                                            jv_kind_name(jv_get_kind(t)),
+                                            jv_kind_name(jv_get_kind(k))));
+    jv_free(t);
+    jv_free(k);
+  }
+  return ret;
+}
+
 // assumes keys is a sorted array
 jv jv_dels(jv t, jv keys) {
   assert(jv_get_kind(keys) == JV_KIND_ARRAY);
index 561f10835357de714ef044fb9dfc28bf0009c2e9..5a47b70c0717ec4a54619762a4cf47a01d1fb223 100644 (file)
--- a/jv_aux.h
+++ b/jv_aux.h
@@ -5,6 +5,7 @@
 
 jv jv_get(jv t, jv k);
 jv jv_set(jv t, jv k, jv v);
+jv jv_has(jv t, jv k);
 jv jv_setpath(jv root, jv path, jv value);
 jv jv_getpath(jv root, jv path);
 jv jv_delpaths(jv root, jv paths);