Better merge example

This commit is contained in:
Mike Farah 2021-11-29 21:29:05 +11:00
parent a1db47122d
commit 3e0e2c83ed

View File

@ -234,25 +234,30 @@ will output
``` ```
## Merge arrays of objects together, matching on a key ## Merge arrays of objects together, matching on a key
There are two parts of the complex expression. The first part is doing the hard work, it creates a map from the arrays keyed by '.a', There are several parts of the complex expression.
so that there are no duplicates. The second half converts that map back to an array. The first part is doing the hard work, it creates a map from the arrays keyed by '.a', so that there are no duplicates.
Then there's another reduce that converts that map back to an array.
Finally, we set the result of the merged array back into the first doc.
To use this, you will need to update '.[]' to be the expression to your array (e.g. .my.array[]), and '.a' to be the key field of your array (e.g. '.name') To use this, you will need to update '.myArray' to be the expression to your array (e.g. .my.array), and '.a' to be the key field of your array (e.g. '.name')
Thanks Kev from [stackoverflow](https://stackoverflow.com/a/70109529/1168223) Thanks Kev from [stackoverflow](https://stackoverflow.com/a/70109529/1168223)
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
myArray:
- a: apple - a: apple
b: appleB b: appleB
- a: kiwi - a: kiwi
b: kiwiB b: kiwiB
- a: banana - a: banana
b: bananaB b: bananaB
something: else
``` ```
And another sample another.yml file of: And another sample another.yml file of:
```yaml ```yaml
myArray:
- a: banana - a: banana
c: bananaC c: bananaC
- a: apple - a: apple
@ -263,12 +268,16 @@ And another sample another.yml file of:
then then
```bash ```bash
yq eval-all ' yq eval-all '
((.[] | {.a: .}) as $item ireduce ({}; . * $item )) as $uniqueMap (
((.myArray[] | {.a: .}) as $item ireduce ({}; . * $item )) as $uniqueMap
| ( $uniqueMap | to_entries | .[]) as $item ireduce([]; . + $item.value) | ( $uniqueMap | to_entries | .[]) as $item ireduce([]; . + $item.value)
) as $mergedArray
| select(fi == 0) | .myArray = $mergedArray
' sample.yml another.yml ' sample.yml another.yml
``` ```
will output will output
```yaml ```yaml
myArray:
- a: apple - a: apple
b: appleB2 b: appleB2
- a: kiwi - a: kiwi
@ -278,6 +287,7 @@ will output
c: bananaC c: bananaC
- a: dingo - a: dingo
c: dingoC c: dingoC
something: else
``` ```
## Merge to prefix an element ## Merge to prefix an element