| category | remark | keyword/ symbol (-pattern) [1] |
apath | input [1] | result | grammar/ workbench [2] |
|---|---|---|---|---|---|---|
| Selection | ||||||
| property | <id> | cat.age | { "cat": { "age": 1 } } | 1 | ||
| property literal | non-identifier properties names | ` ... ` |
cat.`#id` | { "cat": { "#key": 8, "#id": 7 } } | 7 | |
| property regex | all properties with names conforming to a regex | / ... / | cat./#.*/ | 8 , 7 | ||
| dynamic property | expression value used as the property name | prop( ... ) | cat.prop(p) | { "cat": { "age": 8, "p": "age" } } | 8 | |
| children (array) | all array items | * | names.* | {"names": ["jo", "lu"]} | "jo" , "lu" | |
| children (object) | all property values | cat.* | { "cat": { "age": 1, "name": "jo" } } | 1 , "jo" | ||
| self | current context node ('_' or 'self') | _ | self | cat._ | { "age": 1, "name": "jo" } | ||
| Restriction | ||||||
| filter (predicate) | ... ?( ... ) | *?(age==1) | [{"age": 1}, {"age": 2}] | { "age": 1 } | ||
| subscript | ... [ ... ] | names[1] | {"names": ["jo", "lu"]} | "lu" | ||
| value regex | values conforming to a regex | match( ... ) | *?(age.match('1|2')) | [{"age": 1}, {"age": 9}, {"age": 11}] | { "age": 1 } , { "age": 11 } | |
| regex groups | yields a match object with groups | names.*.match('j(o)') | {"names": ["jo", "lu"]} | { "groups": [ "jo", "o" ] } | ||
| regex named groups | match object contains named groups | names.*.match('(?<x>.)u') | { "groups": [ "lu", "l" ], "x": "l" } | |||
| Construction | ||||||
| construction (object) | property name: identifier or string | { ... } | cat.{ id: 2, '#call': name } | { "cat": { "age": 1, "name": "jo" } } | { "id": 2, "#call": "jo" } | |
| ... dynamic property | expression value used as the property name | cat.{ prop(p): 'jo' } | { "cat": { "age": 1, "p": "name" } } | { "name": "jo" } | ||
| ... embedding | value is embedded, here 'self' ('_'), age is newly assigned, and id is removed | cat.{ _, age: 3, id: none } | { "cat": { "age": 1, "name": "jo", "id": 3 } } | { "age": 3, "name": "jo" } | ||
| construction (array) | [ ... ] | cat.[ 3, age ] | { "cat": { "age": 1, "p": "name" } } | [ 3, 1 ] | ||
| ... sequences | sequences are embedded flat. use [names.*] otherwise | cat.[ names.*, 'lu' ] | { "cat": { "names": ["jo", "miau"] } } | [ "jo", "miau", "lu" ] | ||
| Basic Expressions | ||||||
| equality | ==, != | cat.(age == 1) | { "cat": { "age": 1, "name": "jo" } } | true | ||
| relational | <, >, <=, >= | cat.(age < 2) | true | |||
| logical | and, or, not | cat.(age==1 or not age<9) | true | |||
| arithmetic | +, -, *, /, % | cat.(age + 3 * -1) | -2 | |||
| Composite Expressions | ||||||
| scope expression | evaluates sequentially and returns value of last expression | ... , ... | cat.(a = age, name + $a) | { "cat": { "age": 1, "name": "jo" } } | "jo1" | |
| conditional | expression value depending on a condition | if ( ... ) ... | cat.(if (age < 10) age 'old') | 1 | ||
| Variables | ||||||
| variable reference | e.g. predefined variable 'root' for the input | $ ... | $root.cat | { "cat": { "age": 1 } } | { "age": 1 } | |
| variable assignment | usual assignment of values | <id> = ... | toLive = 15 - cat.age, $toLive |
14 | ||
| ... memoizing nodes | a node is bound to a variable, referenced in subsequent paths | cat.(child=_, mom.('gave birth at age ' + (age - $child.age))) |
{ "cat": { "mom": {"age": 5}, "age": 2 }} |
"gave birth at age 3" | ||
| ... joins | "joins" with variables storing sequences | cats = cats.*, dogs = dogs.*, $cats.(cat=_, $dogs ?(_ != $cat). ($cat + ' loves ' + _)) |
{ "cats": ["jo", "lu"], "dogs": ["bay", "jo"] } |
"jo loves bay" , "lu loves bay" , "lu loves jo" | ||
| Step Functions | ||||||
| reusable expressions | simple expressions over the context node | func <id>(...) = ... | func plus(k) = _ + $k, cat.age.plus(10) |
{ "cat": { "age": 1, "name": "jo" } } | 11 | |
| constructive function | constructions over the context node; 'name' relative to it | func callName(x) = { id: $x, '#call': name }, cat.callName(2) |
{ "id": 2, "#call": "jo" } | |||
| recursive function | with global and local variables | to = 5, func recIncr(x) = ( y = $x + 1, if ($y == $to) $y recIncr($y)), cat.recIncr(age) |
5 |
| category | remark | keyword/ symbol (-pattern) [1] |
apath | input [1] | result | grammar/ workbench [2] |
step functions |
|---|---|---|---|---|---|---|---|
| JS Step Functions | |||||||
| simple step function | <id>( ... ) | cat.age.add(1) | { "cat": { "age": 1 } } | 2 | [ // 'ctx_node' (context node) is the object passed // from the previous step - followed by parameters function add(ctx_node, k) { return typeof ctx_node === 'number' && typeof k === 'number' ? ctx_node + k : undefined // 'undefined' stops evaluation with no solution } ] |
||
| with sequences as parameters | sum(keys.*) | {"keys": [1, 2, 3]} | 6 | [ function sum(ctx_node, seq) { let sum = 0 if (!apart.isApathIterable(seq)) return seq for (const x of seq) sum += x return sum } ] |
|||
| returning sequences | cat.age.to(3) | { "cat": { "age": 1 } } | 1 , 2 , 3 | [ // a sequence is returned by using a generator. in general an iterable function* to(ctx_node, k) { for (let i = ctx_node; i <= k; i++) yield i } ] |
empty cells adopt content from previous ones within one category
Link to grammar diagram (superordinate diagram or part of it) and link to the workbench