Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: Optional default argument for $lookup() #732

Open
skwashd opened this issue Jan 24, 2025 · 2 comments
Open

Feature Request: Optional default argument for $lookup() #732

skwashd opened this issue Jan 24, 2025 · 2 comments

Comments

@skwashd
Copy link

skwashd commented Jan 24, 2025

I was introduced to JSONata via Amazon Step Functions. Overall I am enjoying working with it. One missing feature has started to stand out for me.

I'm using $exists($lookup(object, key)) ? $lookup(object, key) : default a lot. This would be simplified if $lookup(object, key, default) was available. The default argument would be optional and default to undefined.

Is this something you would consider adding to JSONata?

@andrew-coleman
Copy link
Member

This seems like a reasonable enhancement, although it does raise a question which I'll come onto in a bit.

However, you can achieve the same result with less code by taking advantage of the sequence flattening rules which will eliminate any non-existent items from the sequence. So if you form an array containing the result of $lookup(object, key) followed by default, and select the first element of that array, then it will return the default if the object key doesn't exist.

I.e. [$lookup(object, key), default][0]

If you know the name of the key up front (i.e. you don't have to calculate the name in a subexpression), then you can use the . operator rather than the $lookup function: object.[key, "default"][0].

See example here where the OrderID of the first Order doesn't exist.

Note that this syntax allows you to specify an ordered sequence of several different optional values from arbitrary subexpressions before defaulting to the final value. It's equivalent to the COALESCE function in SQL.

Coming back to your original request, we would need to think about how it would behave if the first argument was an array of objects rather than a single object (https://docs.jsonata.org/object-functions#lookup). It could either:

  1. Return default if none of the objects contained the key. I.e. you'd only ever get a single default value. Your expression and the equivalent [$lookup(object, key), default][0] behaves like that. So would [object.key, "default"][0].

or

  1. Return default for each object that doesn't contain key. So the resultant array would be the same size as the input array, with potentially multiple instances of default interleaved throughout. object.[key, "default"][0] behaves like that.

@skwashd
Copy link
Author

skwashd commented Jan 24, 2025

@andrew-coleman thanks for the detailed reply. I appreciate it.

Using [$lookup(object, key), default][0] will work for my use case. It isn't perfect, but it is definitely a cleaner way of getting the job done. For the untrained eye it is a little unclear what is happening, but that is what comments are for.

When I submitted this issue, I hadn't thought about the case where object is an array of objects. Option 1 makes most sense. If someone wants option 2, they could use object.[key, "default"][0].

I have a suitable workaround that solves my immediate need. I still think there is merit in $lookup(object, key, default). If you (or the community) don't feel like it is worth the effort, I am happy for this issue to be closed WONTFIX.

Thanks again

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants