DocGuy
DocGuy

Reputation: 45

Use jq to append value of one key to another key, but at a different level of document tree

I want to output this entire JSON file to a new file but with the value of filter-values appended as a string to each description of the filter item in each parameters array.

Some notes:

{
  "empty": {},
  "paths": {
    "somepath": {
      "foo": {
        "parameters": [
          {
            "name": "page"
          },
          {
            "name": "sort"
          },
          {
            "name": "filter",
            "description": "This is the `filter` param."
          },
          {
            "name": "orderby",
            "description": "This is the `orderby` param."
          }
        ],
        "filter-values": [
          "1",
          "2",
          "3"
        ],
        "orderby-values": [
          "a",
          "b",
          "c"
        ]
      },
      "bar": {}
    },
    "anotherpath": {
      "foo": {
        "parameters": [
          {
            "name": "page"
          },
          {
            "name": "filter",
            "description": "This is the `filter` param."
          }
        ],
        "filter-values": [
          "4",
          "5",
          "6"
        ]
      }
    },
    "yetanotherpath": {
      "foo": {
        "parameters": [
          {
            "name": "page"
          }
        ]
      }
    }
  }
}

This is the closest I have come to getting it to work:

(.paths[].foo."filter-values" // empty | join(", ")) as $filters 
| (.paths[].foo.parameters // empty 
| . [] 
| select(.name? == "filter")).description |= . + " Possible values are: " + $filters

Expected output:

{
  "empty": {},
  "paths": {
    "somepath": {
      "foo": {
        "parameters": [
          {
            "name": "page"
          },
          {
            "name": "sort"
          },
          {
            "name": "filter",
            "description": "This is the `filter` param. Possible values are: 1, 2, 3"
          },
          {
            "name": "orderby",
            "description": "This is the `orderby` param."
          }
        ],
        "filter-values": [
          "1",
          "2",
          "3"
        ],
        "orderby-values": [
          "a",
          "b",
          "c"
        ]
      },
      "bar": {}
    },
    "anotherpath": {
      "foo": {
        "parameters": [
          {
            "name": "page"
          },
          {
            "name": "filter",
            "description": "This is the `filter` param. Possible values are: 4, 5, 6"
          }
        ],
        "filter-values": [
          "4",
          "5",
          "6"
        ]
      }
    },
    "yetanotherpath": {
      "foo": {
        "parameters": [
          {
            "name": "page"
          }
        ]
      }
    }
  }
}


Actual output (the entire document is produced twice, with the wrong filter-values appended to the description in some cases):

{
  "empty": {},
  "paths": {
    "somepath": {
      "foo": {
        "parameters": [
          {
            "name": "page"
          },
          {
            "name": "sort"
          },
          {
            "name": "filter",
            "description": "This is the `filter` param. Possible values are: 1, 2, 3"
          },
          {
            "name": "orderby",
            "description": "This is the `orderby` param."
          }
        ],
        "filter-values": [
          "1",
          "2",
          "3"
        ],
        "orderby-values": [
          "a",
          "b",
          "c"
        ]
      },
      "bar": {}
    },
    "anotherpath": {
      "foo": {
        "parameters": [
          {
            "name": "page"
          },
          {
            "name": "filter",
            "description": "This is the `filter` param. Possible values are: 1, 2, 3" 
          }
        ],
        "filter-values": [
          "4",
          "5",
          "6"
        ]
      }
    },
    "yetanotherpath": {
      "foo": {
        "parameters": [
          {
            "name": "page"
          }
        ]
      }
    }
  }
}
{
  "empty": {},
  "paths": {
    "somepath": {
      "foo": {
        "parameters": [
          {
            "name": "page"
          },
          {
            "name": "sort"
          },
          {
            "name": "filter",
            "description": "This is the `filter` param. Possible values are: 4, 5, 6"
          },
          {
            "name": "orderby",
            "description": "This is the `orderby` param."
          }
        ],
        "filter-values": [
          "1",
          "2",
          "3"
        ],
        "orderby-values": [
          "a",
          "b",
          "c"
        ]
      },
      "bar": {}
    },
    "anotherpath": {
      "foo": {
        "parameters": [
          {
            "name": "page"
          },
          {
            "name": "filter",
            "description": "This is the `filter` param. Possible values are: 4, 5, 6"
          }
        ],
        "filter-values": [
          "4",
          "5",
          "6"
        ]
      }
    },
    "yetanotherpath": {
      "foo": {
        "parameters": [
          {
            "name": "page"
          }
        ]
      }
    }
  }
}

Upvotes: 0

Views: 615

Answers (1)

pmf
pmf

Reputation: 36296

Would this do what you want?

(.paths[].foo | select(all(has("parameters", "filter-values"); .))) |= (
  (.parameters[] | select(.name == "filter").description) +=
    " Possible values are: \(."filter-values" | join(", "))"
)
{
  "empty": {},
  "paths": {
    "somepath": {
      "foo": {
        "parameters": [
          {
            "name": "page"
          },
          {
            "name": "sort"
          },
          {
            "name": "filter",
            "description": "This is the `filter` param. Possible values are: 1, 2, 3"
          },
          {
            "name": "orderby",
            "description": "This is the `orderby` param."
          }
        ],
        "filter-values": [
          "1",
          "2",
          "3"
        ],
        "orderby-values": [
          "a",
          "b",
          "c"
        ]
      },
      "bar": {}
    },
    "anotherpath": {
      "foo": {
        "parameters": [
          {
            "name": "page"
          },
          {
            "name": "filter",
            "description": "This is the `filter` param. Possible values are: 4, 5, 6"
          }
        ],
        "filter-values": [
          "4",
          "5",
          "6"
        ]
      }
    },
    "yetanotherpath": {
      "foo": {
        "parameters": [
          {
            "name": "page"
          }
        ]
      }
    }
  }
}

Demo

Upvotes: 1

Related Questions