Home > OS >  Using reduce function to convert array to object
Using reduce function to convert array to object

Time:12-17

I want from the array (an output of another jq from a large json file) of this sort:

[
  {
    "Action": {
      "name1": {
        "product": {
          "summary": "Summary Product"
        }
      }
    }
  },
  {
    "Action": {
      "name2": {
        "gproduct": {
          "summary": "Summary Product"
        }
      }
    }
  },
  {
    "Action": {
      "name3": {
        "product1": {
          "summary": "Summary Product1"
        }
      }
    }
  },
  {
    "Action": {
      "name3": {
        "product2": {
          "summary": "Summary Product2"
        }
      }
    }
  }
]

To obtain:

{
  "Action": {
    "name1": {
      "product": {
        "summary": "Summary Product"
      }
    },
    "name2": {
      "gproduct": {
        "summary": "Summary Product"
      }
    },
    "name3": {
      "product1": {
        "summary": "Summary Product1"
      }
    },
    "name3": {
      "product2": {
        "summary": "Summary Product2"
      }
    }
  }
}

Using the jq: reduce .[] as $o ({}; reduce ($o|keys)[] as $key (.; .[$key] = $o[$key] )) gives:

{
  "Action": {
    "name1": {
      "product": {
        "summary": "Summary Product"
      }
    },
    "name2": {
      "gproduct": {
        "summary": "Summary Product"
      }
    },
    "name3": {
      "product2": {
        "summary": "Summary Product2"
      }
    }
  }
}

In the output file, name3 is listed only with the second product, I want all the products to be listed separately. If more than a product is available under a nameX, the result lists only the last product.

CodePudding user response:

You can use the multiplication operator for recursive merges.

reduce .[] as $obj ({}; . * $obj)

Online demo

  • Related