-
Notifications
You must be signed in to change notification settings - Fork 4
Preview
JMESPath Community introduces the let-expression
function
to supports nested lexical scopes.
let $foo = bar in {a: myvar, b: $foo}
The first argument is a JSON object that introduces a new lexical scope.
The second argument is an expression-type
that is evaluated against the current context – i.e the current result of JMESPath evaluation context, that can be referred to by the @
node. The expression-type
also has access to the stack of nested scopes.
Consider the following example:
let $first_choice = first_choice in states[?name == $first_choice].cities[]
{"first_choice": "WA",
"states": [
{"name": "WA", "cities": ["Seattle", "Bellevue", "Olympia"]},
{"name": "CA", "cities": ["Los Angeles", "San Francisco"]},
{"name": "NY", "cities": ["New York City", "Albany"]}
]
}
When evaluating the states
identifier, JMESPath no longer has access to the root scope, where first_choice
is defined. Therefore, under normal circumstances, the filter-expression
[?name === first_choice]
would evaluate the first_choice
identifier and return an empty array.
Instead, let()
defined the identifier first_choice
has taking the value of the property with the same name in the input JSON document. It effectively created a scope that can be represented as the following JSON object:
{ "first_choice": "WA" }
Therefore, when evaluating the filter-expression
, the first_choice
identifier is indeed defined, and produces the correct result.
JMESPath Community now supports arithmetic-expression
syntax with the usual operators.
{ a: a, b: b, c: b × `2` } | a ÷ ( b − c)
{
"a": 40,
"b": 2
}
As a JSON query language, JMESPath Community now supports functions to manipulate JSON objects.
The items()
function allows you to deconstruct a JSON object to its key and values,
whereas the from_items()
function will combine two arrays into a single JSON object.
from_items(items(@))
{
"foo": "lorem",
"bar": "ipsum",
"baz": "dolor"
}
The zip()
function comes the Python language. It combines two or more arrays into a set of arrays,
each of which contains the _i_th indexed item from each indivual array.
For better understanding, consider the following example:
zip(people, country, fruits)
{
"fruits": ["Orange", "Apple", "Strawberry"],
"people": ["John", "Marc", "Paul"],
"country": ["Germany", "France", "USA" ]
}
Think of the three fruits
, people
and country
arrays as being rows in a table.
Each array has a number of items that you can think of as being the columns in the table.
The zip()
function will create as many arrays as there are full columns, each of which
will contain the items found in each row of the table.
So, the first array – corresponding to the first column of the table – will contain
one item from the people
row, one item from the country
row and finally one item from the fruits
row,
resulting in ["John", "Germany", "Orange"]
.
The second array – corresponding to the second column of the table – contains ["Marc", "France", "Apple"]
.
Using slice-expression
to slice strings is popular in modern programming languages. JMESPath Community supports slicing strings using the same syntax:
foo[:4]
{
"foo": "Hello, world!",
"bar": ["h", "e", "l", "l", "o", " ", "w", "o", "r", "l", "d", "!"]
}
Note: slice-expression
applied to JSON arrays result in a projection. Applying a slice-expression
to a JSON string, however, produces a JSON string.
Using the group_by()
function, you can group collection of objects with specific criteria:
group_by(items, &spec.nodeName)
{
"items": [
{ "spec": { "nodeName": "node_01", "other": "values_01" } },
{ "spec": { "nodeName": "node_02", "other": "values_02" } },
{ "spec": { "nodeName": "node_03", "other": "values_03" } },
{ "spec": { "nodeName": "node_01", "other": "values_04" } }
]
}