-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
def nth(n; g): last(limit(n + 1; g));
does not match my intuition for what "the nth output of g" means when there are fewer than n+1 outputs of g.
Expected behavior
nth($n; exp)
should probably be analogous to [exp][$n]
(i.e. ([exp]|.[$n])
), except less expensive and without evaluating the $n+1th and subsequent outputs of exp.
One thing to note is that $array[$n] != $array[:$n][-1]
, but more closely matches $array[$n:][0]
... If $n is greater than the number of outputs, I'd expect to get back either empty or null. This implies something more like the following:
def drop($n; g): foreach g as $_ ($n; .-1; . < 0 or empty|$_);
def nth($n; g): first(drop($n; g), null);
Additional context
I thought I'd found a more efficient implementation of nth
in the following, but well, the above:
diff --git a/src/builtin.jq b/src/builtin.jq
index a6cdabe..509047c 100644
--- a/src/builtin.jq
+++ b/src/builtin.jq
@@ -165,7 +165,9 @@ def any(condition): any(.[]; condition);
def all: all(.[]; .);
def any: any(.[]; .);
def last(g): reduce . as $_ (.; g|[.]) | .[]?;
-def nth($n; g): if $n < 0 then error("nth doesn't support negative indices") else last(limit($n + 1; g)) end;
+def nth($n; g):
+ if $n < 0 then error("nth doesn't support negative indices")
+ else label $out | foreach g as $_ ($n; .-1; . < 0 or empty|$_, break $out) end;
def first: .[0];
def last: .[-1];
def nth($n): .[$n];
This would be kind of a gratuitous incompatibility but might be nice for 2.0.
(The above first/drop implementation runs just as fast but reads nicer IMO.)