Skip to content

Commit 48be232

Browse files
committed
Add the "has" function. Closes #74.
1 parent 88a6dc5 commit 48be232

File tree

4 files changed

+49
-0
lines changed

4 files changed

+49
-0
lines changed

builtin.c

+1
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,7 @@ static const struct cfunction function_list[] = {
480480
{(cfunction_ptr)jv_setpath, "setpath", 3}, // FIXME typechecking
481481
{(cfunction_ptr)jv_getpath, "getpath", 2},
482482
{(cfunction_ptr)jv_delpaths, "delpaths", 2},
483+
{(cfunction_ptr)jv_has, "has", 2},
483484
{(cfunction_ptr)f_equal, "_equal", 3},
484485
{(cfunction_ptr)f_notequal, "_notequal", 3},
485486
{(cfunction_ptr)f_less, "_less", 3},

docs/content/3.manual/manual.yml

+19
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,25 @@ sections:
453453
input: '[42,3,35]'
454454
output: ['[0,1,2]']
455455

456+
- title: `has`
457+
body: |
458+
459+
The builtin function `has` returns whether the input object
460+
has the given key, or the input array has an element at the
461+
given index.
462+
463+
`has($key)` has the same effect as checking whether `$key`
464+
is a member of the array returned by `keys`, although `has`
465+
will be faster.
466+
467+
examples:
468+
- program: 'map(has("foo"))'
469+
input: '[{"foo": 42}, {}]'
470+
output: ['[true, false]']
471+
- program: 'map(has(2))'
472+
input: '[[0,1], ["a","b","c"]]'
473+
output: ['[false, true]']
474+
456475
- title: `select`
457476
body: |
458477

jv_aux.c

+28
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,34 @@ jv jv_set(jv t, jv k, jv v) {
6060
return t;
6161
}
6262

63+
jv jv_has(jv t, jv k) {
64+
assert(jv_is_valid(t));
65+
assert(jv_is_valid(k));
66+
jv ret;
67+
if (jv_get_kind(t) == JV_KIND_NULL) {
68+
jv_free(t);
69+
jv_free(k);
70+
ret = jv_false();
71+
} else if (jv_get_kind(t) == JV_KIND_OBJECT &&
72+
jv_get_kind(k) == JV_KIND_STRING) {
73+
jv elem = jv_object_get(t, k);
74+
ret = jv_bool(jv_is_valid(elem));
75+
jv_free(elem);
76+
} else if (jv_get_kind(t) == JV_KIND_ARRAY &&
77+
jv_get_kind(k) == JV_KIND_NUMBER) {
78+
jv elem = jv_array_get(t, (int)jv_number_value(k));
79+
ret = jv_bool(jv_is_valid(elem));
80+
jv_free(elem);
81+
} else {
82+
ret = jv_invalid_with_msg(jv_string_fmt("Cannot check whether %s has a %s key",
83+
jv_kind_name(jv_get_kind(t)),
84+
jv_kind_name(jv_get_kind(k))));
85+
jv_free(t);
86+
jv_free(k);
87+
}
88+
return ret;
89+
}
90+
6391
// assumes keys is a sorted array
6492
jv jv_dels(jv t, jv keys) {
6593
assert(jv_get_kind(keys) == JV_KIND_ARRAY);

jv_aux.h

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
jv jv_get(jv t, jv k);
77
jv jv_set(jv t, jv k, jv v);
8+
jv jv_has(jv t, jv k);
89
jv jv_setpath(jv root, jv path, jv value);
910
jv jv_getpath(jv root, jv path);
1011
jv jv_delpaths(jv root, jv paths);

0 commit comments

Comments
 (0)