jmespath / jmespath/jmespath.jep
Spec change - merge() function
- Dominant language
- Python
- Stars
- 10
- Forks
- 3
- PR merge metrics
- No merged PRs in 30d
Description
## Background
In all the example given in the spec page for the [merge()](https://jmespath.org/specification.html#merge) function`LITERAL` types are provided as arguments to the function. While this demonstrates the behaviour it is **not at all** useful in practical terms. Literals can only be explicitly defined by the editor of an expression. Much more useful would be to merge on results of expressions or on projections.
### Examples:
```javascript
search([{a: "AY", x: "EX"}, {a: "EY", b: "BEE"}], 'merge(@)')
// OUTPUTS: {"a": "EY", "b": "BEE", "x": "EX"}
search([{a: "AY", x: "EX"}, {a: "EY", b: "BEE"}], 'merge([{FED: @[0].x}, {BAR: @[1].b}])')
// OUTPUTS: {"BAR": "BEE", "FED": "EX"}
```
In order to do this merge would have to accept either TYPE_OBJECT or TYPE_ARRAY to work and the function would need to be able to switch on either type to handle this.
### Discussion
Array can contain any value and ideally we may want to restrict it to a new `TYPE_ARRAY_OBJECT` type so that we can guarantee only objects can be used in the merge. One interesting side effect of this in javascript is that merging arrays results in array members being keyed in their index. This means we can do the following with very little code change:
```javascript
search([{"A": "ONE"}, "TWO", {"C": "THREE"}], 'merge(@)')
// OUTPUTS: {"0": "ZERO", "A": "ONE", "C": "THREE"}
// With all JSON array member types:
search([{"A": "ONE"}, true, null, "BAR", ["ZERO"], 666], 'merge(@)')
// OUTPUTS: {"0": "ZERO", "1": "A", "2": "R", "A": "ONE"}
```
## Implementation in jmespath.ts
```javascript
// Runtime
private functionMerge: RuntimeFunction = resolvedArgs => {
let merged = {};
for (let i = 0; i < resolvedArgs.length; i += 1) {
const current = resolvedArgs[i];
if (Array.isArray(current)) {
merged = Object.assign(merged, ...current);
} else {
merged = Object.assign(merged, current);
}
}
return merged;
};
// and in the function table
merge: {
_func: this.functionMerge,
_signature: [
{
types: [InputArgument.TYPE_OBJECT, InputArgument.TYPE_ARRAY],
variadic: true,
},
],
},
```
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.