1

Using jq, how can I transform:

{ "a": {"b": 0}, "c": {"d": 1}}

into:

{"b": {"a": 0}, "d": {"c": 1}}

without knowing the name of the keys in the source?

(I know that this can lose data in the general case, but not with my data)

3 Answers 3

1

Here's an alternative using with_entries:

with_entries(.key as $parent
  | (.value|keys[0]) as $child
  | {
        key: $child,
        value: { ($parent): .value[$child] }
    }
)
Sign up to request clarification or add additional context in comments.

Comments

0
def swapper:
  . as $in
  | reduce keys[] as $key
      ( {}; . + ( $in[$key] as $o
                  | ($o|keys[0]) as $innerkey
                  | { ($innerkey): { ($key): $o[$innerkey] } } ) ) ;

Example:

{ "a": {"b": 0}, "c": {"d": 1}} | swapper

produces:

{"b":{"a":0},"d":{"c":1}}

Comments

0

Here is a solution which uses jq streams and variables:

[
  . as $d
| keys[]
| $d[.] as $v
| ($v|keys[]) as $vkeys
| {
    ($vkeys): {
       (.): ($vkeys|$v[.])
    }
  }
] | add

It is easy to lose track of what is what at the end so to see more clearly what's going on here is a slightly expanded version with additional comments and variables.

[
  . as $d                    # $d:     {"a":{"b":0},"c":{"d": 1}}
| keys[] | . as $k           # $k:     "a", "c"
| $d[$k] as $v               # $v:     {"b": 0}, {"d": 1}
| ($v|keys[]) as $vkeys      # $vkeys: "b", "d"
| ($vkeys|$v[.]) as $vv      # $vv:    0, 1
| {
    ($vkeys): {              # "b": {     "d": {
       ($k): $vv             #   "a": 0      "c": 1
    }                        # }        , }
  }
] | add

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.