1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
|
def not: if . then false else true end;
def in(xs): . as $x | xs | has($x);
def map(f): [.[] | f];
def with_entries(f): to_entries | map(f) | from_entries;
def select(f): if f then . else empty end;
def recurse: recurse(.[]?);
def recurse(f): def r: ., (f | r); r;
def recurse(f; cond): def r: ., (f | select(cond) | r); r;
def while(cond; update):
def _while: if cond then ., (update | _while) else empty end;
_while;
def until(cond; next):
def _until: if cond then . else next | _until end;
_until;
def repeat(f):
def _repeat: f, _repeat;
_repeat;
def range($end): _range(0; $end; 1);
def range($start; $end): _range($start; $end; 1);
def range($start; $end; $step): _range($start; $end; $step);
def min_by(f): _min_by(map([f]));
def max_by(f): _max_by(map([f]));
def sort_by(f): _sort_by(map([f]));
def group_by(f): _group_by(map([f]));
def unique_by(f): _unique_by(map([f]));
def arrays: select(type == "array");
def objects: select(type == "object");
def iterables: select(type | . == "array" or . == "object");
def booleans: select(type == "boolean");
def numbers: select(type == "number");
def finites: select(isfinite);
def normals: select(isnormal);
def strings: select(type == "string");
def nulls: select(. == null);
def values: select(. != null);
def scalars: select(type | . != "array" and . != "object");
def inside(xs): . as $x | xs | contains($x);
def combinations:
if length == 0 then
[]
else
.[0][] as $x | [$x] + (.[1:] | combinations)
end;
def combinations(n): [limit(n; repeat(.))] | combinations;
def walk(f):
def _walk:
if type == "array" then
map(_walk)
elif type == "object" then
map_values(_walk)
end | f;
_walk;
def first: .[0];
def first(g): label $out | g | ., break $out;
def last: .[-1];
def last(g): reduce g as $item (null; $item);
def isempty(g): label $out | (g | false, break $out), true;
def all: all(.);
def all(y): all(.[]; y);
def all(g; y): isempty(g | select(y | not));
def any: any(.);
def any(y): any(.[]; y);
def any(g; y): isempty(g | select(y)) | not;
def limit($n; g):
if $n > 0 then
label $out |
foreach g as $item (
$n;
. - 1;
$item, if . <= 0 then break $out else empty end
)
elif $n == 0 then
empty
else
g
end;
def nth($n): .[$n];
def nth($n; g):
if $n < 0 then
error("nth doesn't support negative indices")
else
label $out |
foreach g as $item (
$n + 1;
. - 1;
if . <= 0 then $item, break $out else empty end
)
end;
def truncate_stream(f):
. as $n | null | f |
if .[0] | length > $n then .[0] |= .[$n:] else empty end;
def fromstream(f):
{ x: null, e: false } as $init |
foreach f as $i (
$init;
if .e then $init end |
if $i | length == 2 then
setpath(["e"]; $i[0] | length == 0) |
setpath(["x"] + $i[0]; $i[1])
else
setpath(["e"]; $i[0] | length == 1)
end;
if .e then .x else empty end
);
def tostream:
path(def r: (.[]? | r), .; r) as $p |
getpath($p) |
reduce path(.[]?) as $q ([$p, .]; [$p + $q]);
def map_values(f): .[] |= f;
def del(f): delpaths([path(f)]);
def paths: path(..) | select(. != []);
def paths(f): paths as $p | select(getpath($p) | f) | $p;
def pick(f): . as $v |
reduce path(f) as $p (null; setpath($p; $v | getpath($p)));
def fromdateiso8601: strptime("%Y-%m-%dT%H:%M:%S%z") | mktime;
def todateiso8601: strftime("%Y-%m-%dT%H:%M:%SZ");
def fromdate: fromdateiso8601;
def todate: todateiso8601;
def match($re): match($re; null);
def match($re; $flags): _match($re; $flags; false)[];
def test($re): test($re; null);
def test($re; $flags): _match($re; $flags; true);
def capture($re): capture($re; null);
def capture($re; $flags): match($re; $flags) | _capture;
def scan($re): scan($re; null);
def scan($re; $flags):
match($re; $flags + "g") |
if .captures == [] then
.string
else
[.captures[].string]
end;
def splits($re): splits($re; null);
def splits($re; $flags): split($re; $flags)[];
def sub($re; str): sub($re; str; null);
def sub($re; str; $flags):
. as $str |
def _sub:
if .matches == [] then
$str[:.offset] + .string
else
.matches[-1] as $r |
{
string: (($r | _capture | str) + $str[$r.offset+$r.length:.offset] + .string),
offset: $r.offset,
matches: .matches[:-1],
} |
_sub
end;
{ string: "", matches: [match($re; $flags)] } | _sub;
def gsub($re; str): sub($re; str; "g");
def gsub($re; str; $flags): sub($re; str; $flags + "g");
def debug(f): (f | debug | empty), .;
def inputs:
try
repeat(input)
catch
if . == "break" then empty else error end;
def INDEX(stream; idx_expr):
reduce stream as $row ({}; .[$row | idx_expr | tostring] = $row);
def INDEX(idx_expr):
INDEX(.[]; idx_expr);
def JOIN($idx; idx_expr):
[.[] | [., $idx[idx_expr]]];
def JOIN($idx; stream; idx_expr):
stream | [., $idx[idx_expr]];
def JOIN($idx; stream; idx_expr; join_expr):
stream | [., $idx[idx_expr]] | join_expr;
def IN(s): any(s == .; .);
def IN(src; s): any(src == s; .);
|