jq
jq copied to clipboard
Update delpaths function to use sort with slicing
Pull Request for #2868
- Added
jv_array_slicefunction to support slicing of the array
Can someone give an example when this happens? also some test for it would be good
@wader Well, I checked my 2023-08-29 chat logs with @nicowilliams and that issue was about the following jq script (that is supposed to delete duplicate elements in the input array without sorting):
[6,5,1,2,5,3,4,6,7,6,5] |
del(
. as $out |
range(length) as $i
.[$i+1:][] |
select(. == $dot[$i])
)
Not working as intended because of its use of slices; output:
$ jq -cn '[6,5,1,2,5,3,4,6,7,6,5] | del(. as $dot | range(length) as $i | .[$i+1:][] | select(. == $dot[$i]))'
[6,5,1,2,3,4,7,5]
$ jq -cn '[6,5,1,2,5,3,4,6,7,6,5] | delpaths([path(. as $dot | range(length) as $i | .[$i+1:][] | select(. == $dot[$i])) | debug])'
["DEBUG:",[{"start":1,"end":null},6]]
["DEBUG:",[{"start":1,"end":null},8]]
["DEBUG:",[{"start":2,"end":null},2]]
["DEBUG:",[{"start":2,"end":null},8]]
["DEBUG:",[{"start":5,"end":null},5]]
["DEBUG:",[{"start":8,"end":null},1]]
[6,5,1,2,3,4,7,5]
(The last duplicate 5 did not get deleted)
This is the usual problem that afflicts path expressions with negative indices and slices; the slice paths do not get canonicalised (or they are not sorted in an order that would make the deletions work correctly), so they end up pointing the wrong elements.
A version of that same script that uses a range to loop the array instead of a slice works correctly:
[6,5,1,2,5,3,4,6,7,6,5] |
del(
. as $dot |
range(length) as $i |
.[range($i + 1; length)] |
select(. == $dot[$i])
)
output:
$ jq -cn '[6,5,1,2,5,3,4,6,7,6,5] | del(. as $dot | range(length) as $i | .[range($i + 1; length)] | select(. == $dot[$i]))'
[6,5,1,2,3,4,7]
$ jq -cn '[6,5,1,2,5,3,4,6,7,6,5] | delpaths([ path(. as $dot | range(length) as $i | .[range($i + 1; length)] | select(. == $dot[$i])) | debug ])'
["DEBUG:",[7]]
["DEBUG:",[9]]
["DEBUG:",[4]]
["DEBUG:",[10]]
["DEBUG:",[10]]
["DEBUG:",[9]]
[6,5,1,2,3,4,7]
I don't really understand this patch, so I am not sure what @capak07 had in mind with it. This does not solve the issue #2868 was created for, but maybe they are trying to solve a different bug?
I don't understand what you mean
Hmm, I am closing this PR since it seems the patch does not solve any issue, and otherwise it does not accomplish anything useful.
This is a tricky bug to fix.