Skip to content

Commit

Permalink
add skip/2 as the counterpart to limit/2 (#3181)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
itchyny authored Oct 5, 2024
1 parent 860af44 commit 1bebd23
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 13 deletions.
16 changes: 13 additions & 3 deletions docs/content/manual/dev/manual.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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: |
Expand Down
23 changes: 19 additions & 4 deletions jq.1.prebuilt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 9 additions & 5 deletions src/builtin.jq
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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];
Expand Down
24 changes: 24 additions & 0 deletions tests/jq.test
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
6 changes: 5 additions & 1 deletion tests/man.test

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 1bebd23

Please sign in to comment.