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

lost with an expression #716

Open
jviure opened this issue Oct 1, 2024 · 3 comments
Open

lost with an expression #716

jviure opened this issue Oct 1, 2024 · 3 comments
Labels

Comments

@jviure
Copy link

jviure commented Oct 1, 2024

Hi, I m getting crazy with this jsonata expression, I don't know why the $append seems not working, the $uniqueIds is always empty at the output indistinctly the lookup value (true, false..), the total variable the same, some idea how to continue? I only need those values updated inside the $map.

(
$uniqueIds := [];
$total := 0;

$map(products.agreements, function($agreement, $i) {
    ($lookup($uniqueIds, $agreement.id) and $agreement[$i].offerType = "OP") ? 
        $uniqueIds := $append($uniqueIds, [$agreement.id]) :
        $total := $total + $agreement.totalAmount 
    }
);

{
    "uniqueIds" : $uniqueIds,
    "total": $total
}

)

some clue? thanks

@markmelville
Copy link
Contributor

markmelville commented Oct 1, 2024

It's almost impossible to know what the expression is meant to do without knowing your input JSON. Try using the exerciser and saving a link. It will capture your input and your expression.

But there are a few problems I could point out:

  • $lookup finds a key on an object, but by passing in "$uniqueIds" it is never going to return true because it's an array, and it's empty.
  • Variables are not reference pointers. They are scoped name bindings, so the inner $uniqueIds gets the value you expect from the append but in the next iteration it's back to being what to the value in the outer scope, an empty array.

You need to think of jsonata expression not as a procedural programming language, but a sort of select statements for JSON data. So, here's a stab at the approach I would take, again without understanding exactly what you want to do or what the input JSON is:

(
  /* groups the agreements by id, and gets the first one from each group that is OP */
  $uniqueIds := products.agreements{id:$[offerType="OP"][0].id};
  
  /* filters out the agreements not in the above list */
  $nonOpAgreements := products.agreements[$not($lookup($uniqueIds,id))];

  {
    "uniqueIds" : $keys($uniqueIds),
    "total": $sum($nonOpAgreements.totalAmount)
  }
)

@jviure
Copy link
Author

jviure commented Oct 1, 2024

Thanks a lot for your time, it's hard for me to understand right now the goal or how it works jsonata, I m dev and this is not a traditional dev language. It's very very fast, this for sure. Finally, with the help of one mate I could afford it:

(
$ofertasOP := products.agreements[offerType = "OP"];
$ofertasOPGroupById := $ofertasOP{id: *};
$uniqueIds := [$keys($ofertasOPGroupById)];
$firstTotalOfEachId := [$map($uniqueIds, function($id) {
$lookup($ofertasOPGroupById, $id)[0].totalAmount
})];

$sum($firstTotalOfEachId);

)

I have an array of products, every product has an array of agreements, I ve to sum the totalAmount of the agreements (only of offerType="OP") once. If there are 5 agreements with id X I only ve to sum once the totalAmount, not 5. Sorry if my explanation is not very well, my english... thanks a lot!

@markmelville
Copy link
Contributor

markmelville commented Oct 4, 2024

JSONata is an expression syntax, like XPath, JMESPath, jq filters, JEXL or SPeL. These all use declarative expressions. Even though JSONata has functions, the $map function is not used as much since it's more idiomatic to use the path mapping operator ., so even where you are using $map, something like:

items.($lookup($ofertasOPGroupById, $)[0].totalAmount)

Back to your scenario, it would be really helpful for you to provide an exerciser link instead of describing the structure of the input. For example, here is my best guess at your input based on your description. Exerciser Link. Make changes, and use this icon to save your version, and share it here.
image

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

No branches or pull requests

3 participants