Skip to content

Pattern matching

Most transformations need only what’s covered so far and the library methods. When you need to decide what to output based on the shape of your data, use a #match expression.

A #match binds a value to a variable, then tries each case from top to bottom. The value of the first case that matches becomes the result.

#is with a type name checks the value’s JSON type:

{
"#match($.somePath as @x) into 'result'": [
{ "#is(object)": "'Found an object'" },
{ "#is(array)": "'Found an array'" },
{ "#is(string)": "'Found a string'" },
{ "#is(integer)": "'Found an integer'" },
{ "#is(decimal)": "'Found a decimal'" },
{ "#is(boolean)": "'Found a boolean'" },
{ "#is(null)": "'Found a null value'" }
]
}

For more flexibility, #given evaluates any boolean expression. It can replace #is or be combined with it. #default() always matches, so use it as the last case to catch everything else.

{
"#match($.somePath as @x) into 'result'": [
{ "#given(#isObject(@x) && #valueOf($.someOther) > 5)": "'Found a specific object'" },
{ "#default()": "'Found something else'" }
]
}

For finer control over arrays, #is accepts an array pattern.

{
"#match($.somePath as @x) into 'result'": [
{ "#is([])": "'Found an empty array'" },
{ "#is([_])": "'Found an array with one or more elements'" },
{ "#is(['test', _])": "'Found an array starting with test, followed by at least one more element'" },
{ "#is([_, _])": "'Found an array with at least two elements'" }
]
}
  • _ is a discard: it matches any value.
  • Literal values such as 'test' must match exactly.
  • A discard at the end of an array pattern matches one or more remaining elements.

Object patterns work the same way and can mix in discards.

{
"#match($.somePath as @x) into 'result'": [
{ "#is({})": "'Found an object with zero or more properties'" },
{ "#is({ 'someName': 'someValue' })": "'Found an object where someName is someValue'" },
{ "#is({ 'someName': { 'nested': _ } })": "'Found an object where someName has a nested property'" },
{ "#is({ 'someName': [_, 'someValue'] })": "'Found an object where someName is an array whose second element is someValue'" }
]
}

An object pattern requires the properties you list. The object may have any number of other properties.

An undeclared variable inside an array or object pattern is set to the value at that position. Variables are bound in the order they appear, so one bound earlier in a case can be used later in the same case. Like lambda variables, they exist only within their case.

{
"#match($.somePath as @x) into 'result'": [
{ "#is({ 'name': @name, 'values': [@firstValue, _] })": "#append('Name is ', @name, ' and first value is ', @firstValue)" },
{ "#is({ 'function': @f }) && #given(#isObject(@f))": "'Found a function object'" }
]
}