From f758f3e6eaad379f3370a39dcf9e8b2cfe4ef419 Mon Sep 17 00:00:00 2001 From: itchyny Date: Sun, 22 Sep 2024 09:44:11 +0900 Subject: [PATCH] add skip/2 as the counterpart to limit/2 --- docs/content/manual/dev/manual.yml | 16 ++++++++++++--- jq.1.prebuilt | 23 +++++++++++++++++---- src/builtin.jq | 10 +++++++--- tests/jq.test | 32 ++++++++++++++++++++++++++++++ tests/man.test | 6 +++++- 5 files changed, 76 insertions(+), 11 deletions(-) diff --git a/docs/content/manual/dev/manual.yml b/docs/content/manual/dev/manual.yml index c98b3ca259..60debde5e5 100644 --- a/docs/content/manual/dev/manual.yml +++ b/docs/content/manual/dev/manual.yml @@ -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: | diff --git a/jq.1.prebuilt b/jq.1.prebuilt index 1d1424f68d..d3e44cfbd1 100644 --- a/jq.1.prebuilt +++ b/jq.1.prebuilt @@ -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\. . diff --git a/src/builtin.jq b/src/builtin.jq index aa33cd4b75..5d3a1bc1db 100644 --- a/src/builtin.jq +++ b/src/builtin.jq @@ -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) +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 exp end; + 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) diff --git a/tests/jq.test b/tests/jq.test index 446ee36952..e82c0892c0 100644 --- a/tests/jq.test +++ b/tests/jq.test @@ -334,6 +334,38 @@ 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(3; .[])] +[] +[] + +[skip(0; .[])] +[1,2,3] +[1,2,3] + +[skip(2; .[])] +[1,2,3] +[3] + +[skip(3; .[])] +[1,2,3] +[] + +[skip(4; .[])] +[1,2,3] +[] + +try skip(-1; error) catch . +null +"skip doesn't support negative count" + [first(range(.)), last(range(.))] 10 [0,9] diff --git a/tests/man.test b/tests/man.test index 6c5eba390a..5529e011ef 100644 --- a/tests/man.test +++ b/tests/man.test @@ -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]