sort_by and group_by functions, tests and docs.
This commit is contained in:
1 parent
ed7f95a492
commit
11965aaa2e
3 files changed
+96
No files matched your search
@@ -221,6 +221,26 @@ static jv f_sort(jv input){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static jv f_sort_by_impl(jv input, jv keys) {
|
||||||
|
if (jv_get_kind(input) == JV_KIND_ARRAY &&
|
||||||
|
jv_get_kind(keys) == JV_KIND_ARRAY &&
|
||||||
|
jv_array_length(jv_copy(input)) == jv_array_length(jv_copy(keys))) {
|
||||||
|
return jv_sort(input, keys);
|
||||||
|
} else {
|
||||||
|
return type_error2(input, keys, "cannot be sorted, as they are not both arrays");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static jv f_group_by_impl(jv input, jv keys) {
|
||||||
|
if (jv_get_kind(input) == JV_KIND_ARRAY &&
|
||||||
|
jv_get_kind(keys) == JV_KIND_ARRAY &&
|
||||||
|
jv_array_length(jv_copy(input)) == jv_array_length(jv_copy(keys))) {
|
||||||
|
return jv_group(input, keys);
|
||||||
|
} else {
|
||||||
|
return type_error2(input, keys, "cannot be sorted, as they are not both arrays");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static jv f_type(jv input) {
|
static jv f_type(jv input) {
|
||||||
jv out = jv_string(jv_kind_name(jv_get_kind(input)));
|
jv out = jv_string(jv_kind_name(jv_get_kind(input)));
|
||||||
jv_free(input);
|
jv_free(input);
|
||||||
@@ -246,6 +266,8 @@ static struct cfunction function_list[] = {
|
|||||||
{(cfunction_ptr)f_type, "type", 1},
|
{(cfunction_ptr)f_type, "type", 1},
|
||||||
{(cfunction_ptr)f_add, "add", 1},
|
{(cfunction_ptr)f_add, "add", 1},
|
||||||
{(cfunction_ptr)f_sort, "sort", 1},
|
{(cfunction_ptr)f_sort, "sort", 1},
|
||||||
|
{(cfunction_ptr)f_sort_by_impl, "_sort_by_impl", 2},
|
||||||
|
{(cfunction_ptr)f_group_by_impl, "_group_by_impl", 2},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct symbol_table cbuiltins = {function_list, sizeof(function_list)/sizeof(function_list[0])};
|
static struct symbol_table cbuiltins = {function_list, sizeof(function_list)/sizeof(function_list[0])};
|
||||||
@@ -271,6 +293,8 @@ static block bind_bytecoded_builtins(block b) {
|
|||||||
static const char* jq_builtins[] = {
|
static const char* jq_builtins[] = {
|
||||||
"def map(f): [.[] | f];",
|
"def map(f): [.[] | f];",
|
||||||
"def select(f): if f then . else empty end;",
|
"def select(f): if f then . else empty end;",
|
||||||
|
"def sort_by(f): _sort_by_impl(map([f]));",
|
||||||
|
"def group_by(f): _group_by_impl(map([f]));",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -487,6 +487,55 @@ sections:
|
|||||||
input: '[1, "1", [1]]'
|
input: '[1, "1", [1]]'
|
||||||
output: ['"1"', '"1"', '"[1]"']
|
output: ['"1"', '"1"', '"[1]"']
|
||||||
|
|
||||||
|
- title: `sort, sort_by`
|
||||||
|
body: |
|
||||||
|
|
||||||
|
The `sort` functions sorts its input, which must be an
|
||||||
|
array. Values are sorted in the following order:
|
||||||
|
|
||||||
|
* `null`
|
||||||
|
* `false`
|
||||||
|
* `true`
|
||||||
|
* numbers
|
||||||
|
* strings, in alphabetical order (by unicode codepoint value)
|
||||||
|
* arrays, in lexical order
|
||||||
|
* objects
|
||||||
|
|
||||||
|
The ordering for objects is a little complex: first they're
|
||||||
|
compared by comparing their sets of keys (as arrays in
|
||||||
|
sorted order), and if their keys are equal then the values
|
||||||
|
are compared key by key.
|
||||||
|
|
||||||
|
`sort_by` may be used to sort by a particular field of an
|
||||||
|
object, or by applying any jq filter. `sort_by(foo)`
|
||||||
|
compares two elements by comparing the result of `foo` on
|
||||||
|
each element.
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- program: 'sort'
|
||||||
|
input: '[8,3,null,6]'
|
||||||
|
output: ['[null,3,6,8]']
|
||||||
|
- program: 'sort_by(.foo)'
|
||||||
|
input: '[{"foo":4, "bar":10}, {"foo":3, "bar":100}, {"foo":2, "bar":1}]'
|
||||||
|
output: ['[{"foo":2, "bar":1}, {"foo":3, "bar":100}, {"foo":4, "bar":10}]']
|
||||||
|
|
||||||
|
- title: `group_by`
|
||||||
|
body: |
|
||||||
|
|
||||||
|
`group_by(.foo)` takes as input an array, groups the
|
||||||
|
elements having the same `.foo` field into separate arrays,
|
||||||
|
and produces all of these arrays as elements of a larger
|
||||||
|
array, sorted by the value of the `.foo` field.
|
||||||
|
|
||||||
|
Any jq expression, not just a field access, may be used in
|
||||||
|
place of `.foo`. The sorting order is the same as described
|
||||||
|
in the `sort` function above.
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- program: 'group_by(.foo)'
|
||||||
|
input: '[{"foo":1, "bar":10}, {"foo":3, "bar":100}, {"foo":1, "bar":1}]'
|
||||||
|
output: ['[[{"foo":1, "bar":10}, {"foo":1, "bar":1}], [{"foo":3, "bar":100}]]']
|
||||||
|
|
||||||
- title: `contains`
|
- title: `contains`
|
||||||
body: |
|
body: |
|
||||||
|
|
||||||
@@ -584,6 +633,21 @@ sections:
|
|||||||
input: 2
|
input: 2
|
||||||
output: ['"many"']
|
output: ['"many"']
|
||||||
|
|
||||||
|
- title: `>, >=, <=, <`
|
||||||
|
body: |
|
||||||
|
|
||||||
|
The comparison operators `>`, `>=`, `<=`, `<` return whether
|
||||||
|
their left argument is greater than, greater than or equal
|
||||||
|
to, less than or equal to or less than their right argument
|
||||||
|
(respectively).
|
||||||
|
|
||||||
|
The ordering is the same as that described for `sort`, above.
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- program: '. < 5'
|
||||||
|
input: 2
|
||||||
|
output: ['true']
|
||||||
|
|
||||||
- title: and/or/not
|
- title: and/or/not
|
||||||
body: |
|
body: |
|
||||||
|
|
||||||
|
|||||||
@@ -433,3 +433,11 @@ false
|
|||||||
sort
|
sort
|
||||||
[42,[2,5,3,11],10,{"a":42,"b":2},{"a":42},true,2,[2,6],"hello",null,[2,5,6],{"a":[],"b":1},"abc","ab",[3,10],{},false,"abcd",null]
|
[42,[2,5,3,11],10,{"a":42,"b":2},{"a":42},true,2,[2,6],"hello",null,[2,5,6],{"a":[],"b":1},"abc","ab",[3,10],{},false,"abcd",null]
|
||||||
[null,null,false,true,2,10,42,"ab","abc","abcd","hello",[2,5,3,11],[2,5,6],[2,6],[3,10],{},{"a":42},{"a":42,"b":2},{"a":[],"b":1}]
|
[null,null,false,true,2,10,42,"ab","abc","abcd","hello",[2,5,3,11],[2,5,6],[2,6],[3,10],{},{"a":42},{"a":42,"b":2},{"a":[],"b":1}]
|
||||||
|
|
||||||
|
(sort_by(.b) | sort_by(.a)), sort_by(.a, .b), sort_by(.b, .c), group_by(.b), group_by(.a + .b - .c == 2)
|
||||||
|
[{"a": 1, "b": 4, "c": 14}, {"a": 4, "b": 1, "c": 3}, {"a": 1, "b": 4, "c": 3}, {"a": 0, "b": 2, "c": 43}]
|
||||||
|
[{"a": 0, "b": 2, "c": 43}, {"a": 1, "b": 4, "c": 14}, {"a": 1, "b": 4, "c": 3}, {"a": 4, "b": 1, "c": 3}]
|
||||||
|
[{"a": 0, "b": 2, "c": 43}, {"a": 1, "b": 4, "c": 14}, {"a": 1, "b": 4, "c": 3}, {"a": 4, "b": 1, "c": 3}]
|
||||||
|
[{"a": 4, "b": 1, "c": 3}, {"a": 0, "b": 2, "c": 43}, {"a": 1, "b": 4, "c": 3}, {"a": 1, "b": 4, "c": 14}]
|
||||||
|
[[{"a": 4, "b": 1, "c": 3}], [{"a": 0, "b": 2, "c": 43}], [{"a": 1, "b": 4, "c": 14}, {"a": 1, "b": 4, "c": 3}]]
|
||||||
|
[[{"a": 1, "b": 4, "c": 14}, {"a": 0, "b": 2, "c": 43}], [{"a": 4, "b": 1, "c": 3}, {"a": 1, "b": 4, "c": 3}]]
|
||||||
Reference in new issue
Block a user