Skip to content

Proposal: JSON Array Slicing Operator #244

@bhinners

Description

@bhinners

It would be useful to be able to slice JSON arrays using JSONata. The equivalent syntax in JSONpath is as follows:

$..book[2]    The third book
$..book[-2]   The second to last book
$..book[0,1]  The first two books
$..book[:2]   All books from index 0 (inclusive) until index 2 (exclusive)
$..book[1:2]  All books from index 1 (inclusive) until index 2 (exclusive)
$..book[-2:]  Last two books
$..book[2:]   Book number two from tail

For me, my actual use case is that I'd like to use JSONata to select the first item in a JSON array (easy enough, [0]), perform an operation on that item, and then, if there are more items in the array, call myself recursively by selecting the remaining items [1..n].

Activity

changed the title [-]JSON Array Slicing Operator Request[/-] [+]Proposal: JSON Array Slicing Operator[/+] on Jun 25, 2018
andrew-coleman

andrew-coleman commented on Jun 28, 2018

@andrew-coleman
Member

This looks like the Python array slice syntax which I agree would be a nice addition.

It is possible currently in JSONata to select multiple items from an array by specifying an array of numbers in the filter. For example, the first two books would be books[[0,1]] with the inner square brackets meaning generate an array containing 0 and 1. Likewise a range of indexes can be generated using the .. operator, e.g. books[[2..6]]. However, the current syntax gets a bit awkward when specifying 'up to the end' of an array. For that, you would need to calculate the length of the array using the $count() function then generate the range from that. For this reason I think the Python slice syntax would make a nice addition.

Alternatively, we could adopt a more XPath-like approach and have syntax for getting the 'context position' (current sequence index while processing the predicate) and 'context size' (length of the sequence). XPath provides the functions position() and last() for these. We could do something similar.

bhinners

bhinners commented on Jun 28, 2018

@bhinners
Author

Thanks for the feedback, Andrew. I think the Python style syntax will be more familiar to users, so I'd lean toward that. As you pointed out, my use case is just like the car and cdr Lisp functions. That would definitely cover my case and probably a lot of others and would be my second preference. Arbitrary slicing seems a little more general, though, and more in line with other widely used languages (well, at least Python and Go).

bn3t

bn3t commented on Jul 15, 2020

@bn3t

I am looking for a way to limit the results of a filtered array (predicate). Was it ever implemented ?

objt-awn

objt-awn commented on Jul 12, 2023

@objt-awn

There is a path operator for this that might be usefull: #
books#$i[$i<10] would fill the variable $i with the index within the array, and then use that index to return only the first 10 books.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @bhinners@bn3t@andrew-coleman@objt-awn

        Issue actions

          Proposal: JSON Array Slicing Operator · Issue #244 · jsonata-js/jsonata