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

$map expression behaves differently depending on whether it's used inside of an object or not #568

Open
tlakomy opened this issue Mar 7, 2022 · 2 comments

Comments

@tlakomy
Copy link
Contributor

tlakomy commented Mar 7, 2022

Hello - first of all, thank you for making JSONata, it's absolutely excellent.

I've noticed an issue which seems to be a bug (reproducible in both JSONata 1.7.0 and 1.8.6, tested in https://try.jsonata.org/ explorer).

Steps to reproduce:

Link: https://try.jsonata.org/7kapj6UKN

  • Use a following input sample JSON file (this issue occurs for any input array):
[
  1,
  2,
  3,
  4,
  5
]
  • Write a JSONata expression that maps through a hardcoded array of two items and stores the result in "item" field.
{
    "item": $map([1, 2], function($number, $index) { { "number": $number, "index": $index } }).{"foo": "bar"}
}

Expected result:

{
  "item": [
    {
      "foo": "bar"
    },
    {
      "foo": "bar"
    },
  ]
}

$mapping over two items should produce two items at the output.

Actual result:

{
  "item": [
    {
      "foo": "bar"
    },
    {
      "foo": "bar"
    },
    {
      "foo": "bar"
    },
    {
      "foo": "bar"
    },
    {
      "foo": "bar"
    },
    {
      "foo": "bar"
    },
    {
      "foo": "bar"
    },
    {
      "foo": "bar"
    },
    {
      "foo": "bar"
    },
    {
      "foo": "bar"
    }
  ]
}

Notes:

  • This issue occurs if instead of a hardcoded array (e.g. [1,2,3]) an array obtained as a result of JSONata expression is used (e.g. Order.Products)
  • This issue does not occur if a $map expression is not assigned to a field inside of an object, for a following JSONata expression:
$map([1, 2], function($number, $index) { { "number": $number, "index": $index } }).{"foo": "bar"}

The result is:

[
  {
    "foo": "bar"
  },
  {
    "foo": "bar"
  }
]

which is to be expected.

@cthorner
Copy link

I’m running into a basic array navigation issue:

Input: [{"a": 1},{"a": 2},{"a": 3}]
Expression: $.a[1]
Result: ** no match **

Expected Result: 2

Here is the Exerciser link: https://try.jsonata.org/Rs_HjiRXm
It looks like the result array lives in

$.a[0] and $.a[0][0][0][0][0]

accessing a directly solves the issue, as in:

a[1]

however, if we change the input slightly:

{
"items": [{"a": 1},{"a": 2},{"a": 3}]
}

it no longer works to access it like this:

items.a[1]

and this returns the entire array:

items.a[0] and items.a[0][0][0][0][0]

Is this related to the issue discussed here?

@cthorner
Copy link

Ok, with some help from the slack channel I think I have a better understanding of this behavior.

$.a[1]

should be written as

($.a)[1]

to get the second element.

and these:

items.a[0] and items.a[0][0][0][0][0]

are equivalent to

$.(a[0]) and $.(((a[0])[0])[0])[0]

So it is a matter of precedence where the right most index is applied first in the case of direct array access. This is different from filtering results where the precedence starts at the left most bracket. I'm not sure that makes sense to me at this point, but at least I understand how it works.

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

Successfully merging a pull request may close this issue.

2 participants