1
1
mirror of https://github.com/wader/fq.git synced 2024-11-25 23:13:19 +03:00

builtin: Add chunk_by, count_by and debug

This commit is contained in:
Mattias Wadman 2021-08-18 16:49:56 +02:00
parent f322e78e8e
commit 77f97aade2
5 changed files with 70 additions and 15 deletions

View File

@ -1,7 +1,3 @@
# same as group_by but counts
def count_by(exp):
group_by(exp) | map([(.[0] | exp), length]);
def protobuf_to_value:
.fields | map({(.name | tostring): (.enum // .value)}) | add;

View File

@ -83,6 +83,12 @@ notable is support for arbitrary-precision integers.
### Functions
- All standard library functions from jq
- `chunk/1`, `chunk_by/1` like `group` but groups consecutively on condition.
- `count_by` like `group_by` but counts groups lengths.
- `debug/1` like `debug/0` but uses arg to produce debug message. `{a: 123} | debug({a}) | ...`.
- `path_to_expr` from `["key", 1]` to `".key[1]"`.
- `expr_to_path` from `".key[1]"` to `["key", 1]`.
- `diff/2` produce diff object between two values.
- `open` open file for reading
- `probe` or `decode` try to automatically detect format and decode
- `mp3`, `matroska`, ..., `<name>`, `decode([name])` try decode as format

View File

@ -45,6 +45,43 @@ def trim: capture("^\\s*(?<str>.*?)\\s*$"; "").str;
# does +1 and [:1] as " "*0 is null
def rpad($s; $w): . + ($s * ($w+1-length))[1:];
# like `group` but groups consecutively on condition
def chunk_by(f):
( . as $a
| length as $l
| if $l == 0 then []
else
( [ foreach $a[] as $v (
{cf: ($a[0] | f), index: 0, start: 0, extract: null};
( ($v | f) as $vf
| (.index == 0 or (.cf == $vf)) as $equal
| if $equal then
( .extract = null
)
else
( .cf = $vf
| .extract = [.start, .index]
| .start = .index
)
end
| .index += 1
);
( if .extract then .extract else empty end
, if .index == $l then [.start, .index] else empty end
)
)
]
| map($a[.[0]:.[1]])
)
end
);
# [1, 2, 2, 3] => [[1], [2, 2], [3]
def chunk: chunk_by(.);
# same as group_by but counts
def count_by(exp):
group_by(exp) | map([(.[0] | exp), length]);
# helper to build path query/generate functions for tree structures with
# non-unique children, ex: mp4_path
def tree_path(children; name; $v):

View File

@ -1,14 +1,29 @@
include "assert";
include "funcs";
[
".",
".a",
".a[0]",
".a[123].bb",
".[123].a",
".[123][123].a",
".\"b b\"",
".\"a \\\\ b\"",
".\"a \\\" b\""
][] | assert("\(.) | expr_to_path | path_to_expr"; .; expr_to_path | path_to_expr)
(
([
".",
".a",
".a[0]",
".a[123].bb",
".[123].a",
".[123][123].a",
".\"b b\"",
".\"a \\\\ b\"",
".\"a \\\" b\""
][] | assert("\(.) | expr_to_path | path_to_expr"; .; expr_to_path | path_to_expr))
,
([
[[], []],
[[1], [[1]]],
[[1,1], [[1,1]]],
[[1,1,2], [[1,1],[2]]],
[[1,1,2,2], [[1,1],[2,2]]],
[[1,2,2,1], [[1],[2,2],[1]]]
][] | assert("\(.) | chunk"; .[1]; .[0] | chunk))
,
([
[[{a:1},{a:1},{a:2}], [[{a:1},{a:1}],[{a:2}]]]
][] | assert("\(.) | chunk_by"; .[1]; .[0] | chunk_by(.a)))
)

View File

@ -4,6 +4,7 @@ def debug:
( ((["DEBUG", .] | tojson), "\n" | stderr)
, .
);
def debug(f): . as $c | f | debug | $c;
# eval f and finally eval fin even on empty or error
def finally(f; fin):