skip to Main Content

I need to restructure some JSON files to clean up the data representation. Part of this restructuring includes grouping similar objects in a parent object rather than relying on a particular property of the object. We will have five "sections" in the files:

attributes, associatedObjects, inheritedObjects, enumerations, which will be used to represent "active" objects, and then a deprecated section that has those same four subgroups to denote, well, "deprecated" objects. The deprecated objects will be subject to later removal.

Given a structure such as:

    "attributes": {
        "alpha": {
            "deprecated": true,
            "description": "A description of alpha.",
            "dataType": "string"
        },
        "beta": {
            "deprecated": false,
            "description": "A description of beta.",
            "dataType": "associated object",
            "associatedObject": "gamma"
        },
        "kappa": {
            "deprecated": false,
            "description": "A description of kappa.",
            "dataType": "string"
        }
    }
}

How might I reorganize the file using jq to appear more like the following?

    "deprecations": {
        "attributes": {
            "alpha": {
                "description": "A description of alpha.",
                "dataType": "string"
            }
        },
        "enumerations": {},
        "associatedObjects": {},
        "inheritedObjects": {}
    },
    "attributes": {
        "kappa": {
            "description": "A description of kappa.",
            "dataType": "string"
        }
    },
    "enumerations": {},
    "associatedObjects": {
        "beta": {
            "description": "A description of beta.",
            "dataType": "gamma"
        }
    },
    "inheritedObjects": {}
}

I’ve only been able to add the new, empty sections (without any nesting) at the same level as attributes via jq '.associatedObjects = {} | .inheritedObjects = {} | .enumerations = {} | .deprecations = {} '

I attempted to move the item flagged as deprecated via this command:

jq '.attributes | keys[] as $k | 
if (.[$k].deprecated == true) then 
(del(.[$k].deprecated) | .deprecated += .[$k] | del(.[$k])) 
else empty end '

but this results in invalid JSON and seems to duplicate the structure. I’ve also not been able to combine it with the creation of the new sections. It appears I don’t have to create those new sections separately and/or beforehand.

What would it take to achieve this goal?

2

Answers


  1. I cannot entirely follow the criteria for your distribution, especially .enumerations and .inheritedObjects are unclear, but this could get you going:

    .attributes | (map_values(select(.dataType == "string")) | {
      deprecations: map_values(select(.deprecated)),
      attributes: map_values(select(.deprecated | not))
    }) + {
      associatedObjects: map_values(select(.dataType == "associated object"))
    }
    
    {
      "deprecations": {
        "alpha": {
          "deprecated": true,
          "description": "A description of alpha.",
          "dataType": "string"
        }
      },
      "attributes": {
        "kappa": {
          "deprecated": false,
          "description": "A description of kappa.",
          "dataType": "string"
        }
      },
      "associatedObjects": {
        "beta": {
          "deprecated": false,
          "description": "A description of beta.",
          "dataType": "associated object",
          "associatedObject": "gamma"
        }
      }
    }
    

    Demo

    Login or Signup to reply.
  2. This should generate the expected output :

    jq '(.attributes | map_values(select(.deprecated))) as $dep
        | .depreciations.attributes = ($dep | map_values(del(.deprecated)))
        | (.attributes | map_values(select(has("associatedObject")))) as $assoc
        | .associatedObjects = ($assoc
                               | map_values(.dataType = .associatedObject)
                               | map_values(del(.deprecated, .associatedObject))
                               )
        | .attributes |= del(.[]|select(.deprecated))
        | .attributes |= del(.[]|select(has("associatedObject")))
        | .attributes[] |= del(.deprecated)
        | .depreciations += { "enumerations": {}, "associatedObjects": {}, "inheritedObjects": {} }
        | . + { "enumerations": {}, "inheritedObjects": {} }
    ' input.json
    
    {
      "attributes": {
        "kappa": {
          "description": "A description of kappa.",
          "dataType": "string"
        }
      },
      "depreciations": {
        "attributes": {
          "alpha": {
            "description": "A description of alpha.",
            "dataType": "string"
          }
        },
        "enumerations": {},
        "associatedObjects": {},
        "inheritedObjects": {}
      },
      "associatedObjects": {
        "beta": {
          "description": "A description of beta.",
          "dataType": "gamma"
        }
      },
      "enumerations": {},
      "inheritedObjects": {}
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search