add skip/2 as the counterpart to limit/2 (#3181)

I also changed the behavior of limit/2 with negative count to emit an error, like nth/2 does.
Also, I redefined nth/2 using skip/2 to minimize the impact of growth of builtin filters.
This commit is contained in:
itchyny authored and GitHub committed 2024-10-06 08:25:38 +09:00
1 parent 860af44fee
commit 1bebd23aad
5 files changed
+70 -13

No files matched your search

+13 -3
View File
@@ -3037,16 +3037,26 @@ sections:
input: '[1,2,3]'
output: ['false']
- title: "`limit(n; exp)`"
- title: "`limit(n; expr)`"
body: |
The `limit` function extracts up to `n` outputs from `exp`.
The `limit` function extracts up to `n` outputs from `expr`.
examples:
- program: '[limit(3;.[])]'
- program: '[limit(3; .[])]'
input: '[0,1,2,3,4,5,6,7,8,9]'
output: ['[0,1,2]']
- title: "`skip(n; expr)`"
body: |
The `skip` function skips the first `n` outputs from `expr`.
examples:
- program: '[skip(3; .[])]'
input: '[0,1,2,3,4,5,6,7,8,9]'
output: ['[3,4,5,6,7,8,9]']
- title: "`first(expr)`, `last(expr)`, `nth(n; expr)`"
body: |
Generated
+19 -4
View File
@@ -1,5 +1,5 @@
.
.TH "JQ" "1" "August 2024" "" ""
.TH "JQ" "1" "September 2024" "" ""
.
.SH "NAME"
\fBjq\fR \- Command\-line JSON processor
@@ -3435,14 +3435,14 @@ jq \'isempty(\.[])\'
.
.IP "" 0
.
.SS "limit(n; exp)"
The \fBlimit\fR function extracts up to \fBn\fR outputs from \fBexp\fR\.
.SS "limit(n; expr)"
The \fBlimit\fR function extracts up to \fBn\fR outputs from \fBexpr\fR\.
.
.IP "" 4
.
.nf
jq \'[limit(3;\.[])]\'
jq \'[limit(3; \.[])]\'
[0,1,2,3,4,5,6,7,8,9]
=> [0,1,2]
.
@@ -3450,6 +3450,21 @@ jq \'[limit(3;\.[])]\'
.
.IP "" 0
.
.SS "skip(n; expr)"
The \fBskip\fR function skips the first \fBn\fR outputs from \fBexpr\fR\.
.
.IP "" 4
.
.nf
jq \'[skip(3; \.[])]\'
[0,1,2,3,4,5,6,7,8,9]
=> [3,4,5,6,7,8,9]
.
.fi
.
.IP "" 0
.
.SS "first(expr), last(expr), nth(n; expr)"
The \fBfirst(expr)\fR and \fBlast(expr)\fR functions extract the first and last values from \fBexpr\fR, respectively\.
.
+9 -5
View File
@@ -149,10 +149,14 @@ def until(cond; next):
def _until:
if cond then . else (next|_until) end;
_until;
def limit($n; exp):
if $n > 0 then label $out | foreach exp as $item ($n; .-1; $item, if . <= 0 then break $out else empty end)
elif $n == 0 then empty
else exp end;
def limit($n; expr):
if $n > 0 then label $out | foreach expr as $item ($n; . - 1; $item, if . <= 0 then break $out else empty end)
elif $n == 0 then empty
else error("limit doesn't support negative count") end;
def skip($n; expr):
if $n > 0 then foreach expr as $item ($n; . - 1; if . < 0 then $item else empty end)
elif $n == 0 then expr
else error("skip doesn't support negative count") end;
# range/3, with a `by` expression argument
def range($init; $upto; $by):
if $by > 0 then $init|while(. < $upto; . + $by)
@@ -169,7 +173,7 @@ def any: any(.[]; .);
def last(g): reduce g as $item (null; $item);
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;
else first(skip($n; g)) end;
def first: .[0];
def last: .[-1];
def nth($n): .[$n];
+24
View File
@@ -334,6 +334,30 @@ null
"badness"
[1]
try limit(-1; error) catch .
null
"limit doesn't support negative count"
[skip(3; .[])]
[1,2,3,4,5,6,7,8,9]
[4,5,6,7,8,9]
[skip(0,2,3,4; .[])]
[1,2,3]
[1,2,3,3]
[skip(3; .[])]
[]
[]
try skip(-1; error) catch .
null
"skip doesn't support negative count"
nth(1; 0,1,error("foo"))
null
1
[first(range(.)), last(range(.))]
10
[0,9]
+5 -1
View File
@@ -873,10 +873,14 @@ isempty(.[])
[1,2,3]
false
[limit(3;.[])]
[limit(3; .[])]
[0,1,2,3,4,5,6,7,8,9]
[0,1,2]
[skip(3; .[])]
[0,1,2,3,4,5,6,7,8,9]
[3,4,5,6,7,8,9]
[first(range(.)), last(range(.)), nth(./2; range(.))]
10
[0,9,5]