Search code examples
jsonjq

How to merge the values from the top-level property to each item in the array?


Here's my sample JSON file:

{
    "Schedules": {
        "Days": [
            "Monday",
            "Tuesday",
            "Wednesday",
            "Thursday",
            "Friday",
            "Saturday",
            "Sunday"
        ],
        "Times": ["8:00 AM", "9:00 AM", "10:00 AM"]
    },
    "Servers": [
        {
            "Name": "Test",
            "Schedules": {
                "Days": [
                    "Monday",
                    "Tuesday",
                    "Wednesday",
                    "Thursday",
                    "Friday"
                ],
                "Times": [
                    "8:30 AM",
                    "1:30 PM",
                    "5:00 PM"
                ]
            }
        },
        {
            "Name": "Staging",
            "Schedules": {
                "Times": [
                    "5:00 PM"
                ]
            }
        }
    ]
}

The top-level "Schedules" is meant as default value for each item in the "Servers" and can be overridden from each item in the "Servers". To achieve this, I'm thinking of copying the top-level "Schedules" and replace the values of the local "Schedules" and use the resulting value to replace the local "Schedules". I tried this command:

jq '.Servers |= map(. + {"Schedules": .Schedules})'

but it seems .Schedules refers to the local "Schedules" instead of the top-level one.

This is what I'm expecting for result:

[
    {
        "Name": "Test",
        "Schedules": {
            "Days": [
                "Monday",
                "Tuesday",
                "Wednesday",
                "Thursday",
                "Friday"
            ],
            "Times": [
                "8:30 AM",
                "1:30 PM",
                "5:00 PM"
            ]
        }
    },
    {
        "Name": "Staging",
        "Schedules": {
            "Days": [
                "Monday",
                "Tuesday",
                "Wednesday",
                "Thursday",
                "Friday",
                "Saturday",
                "Sunday"
            ],
            "Times": [
                "5:00 PM"
            ]
        }
    }
]

Solution

  • Try saving the top level .Schedules to a variable like so:

    .Schedules as $dflt
    | .Servers[].Schedules |= $dflt + .
    | {Servers}