3

I want to remove all the nested arrays and put values of "location" and "metarecord" in the rest json object and finally remove these object ("location" and "metarecord").

{
  "info": [
    {
      "item": "sugar",
      "price": 4,
      "state": "Alberta",
      "country": "Canada"
    },
    {
      "item": "sugar",
      "price": 4.5,
      "state": "California",
      "country": "US"
    }
  ],
  "location": {
    "continent": [
      {
        "country": "US",
        "coordinates": {
          "lang": "97º 00' W",
          "long": "38º 00' N"
        }
      },
      {
        "country": "Canada",
        "coordinates": {
          "lang": "95° 00' W",
          "long": "60° 00' N"
        }
      }
    ]
  },
  "metarecord": {
    "continent": "North America"
  }
}

the below is what i want to achieve: remove all the nested arrays and put values of "location" to their appropriate json objects using value of country (e.g if country value of an object is "Canada" then, location of "canada" should be added) and "metarecord" is to all the objects inside "info" as its general

[
  {
    "continent": "North America",
    "item": "sugar",
    "price": 4,
    "state": "Alberta",
    "country": "Canada",
    "lang": "95° 00' W",
    "long": "60° 00' N"
  },
  {
    "continent": "North America",
    "item": "sugar",
    "price": 4.5,
    "state": "California",
    "country": "US",
    "lang": "97º 00' W",
    "long": "38º 00' N"
  }
]

what i tried:

[
  {
    "operation": "shift",
    "spec": {
      "info": {
        "*": {
          "item": "[&1].item",
          "price": "[&1].price",
          "state": "[&1].state",
          "country": "[&1].country"
        }
      },
      "location": {
        "continent": {
          "@": "[&1].continent"
        }
      },
      "metarecord": {
        "continent": {
          "*": {
            "$": "[&2].&1"
          }
        }
      }
    }
  }
]

output: which is not what i want.

[
  {
    "item": "sugar",
    "price": 4,
    "state": "Alberta",
    "country": "Canada"
  },
  {
    "item": "sugar",
    "price": 4.5,
    "state": "California",
    "country": "US"
  }
]
Barbaros Özhan
  • 59,113
  • 10
  • 31
  • 55
kif
  • 33
  • 4

1 Answers1

1

You can use the following transformation

[
  { // you can group by the countries while matching the ones taken from different arrays
    "operation": "shift",
    "spec": {
      "info": {
        "*": {
          "*": "@1,country.&",
          "@2,location.continent": { // go two levels up the tree to grab the values
            "*": {
              "coordinates": { "*": "@2,country.&" }
            }
          },
          "@2,metarecord.continent": "@1,country.continent"
        }
      }
    }
  },
  { // pick only one from the repeating components for the arrays
    "operation": "cardinality",
    "spec": {
      "*": {
        "*": "ONE"
      }
    }
  },
  { // get rid of the object labels
    "operation": "shift",
    "spec": {
      "*": ""
    }
  }
]

the demo on the site http://jolt-demo.appspot.com/ is :

enter image description here

Barbaros Özhan
  • 59,113
  • 10
  • 31
  • 55
  • thanks @Ozhan, can you check the updated one, i was misunderstood the data. – kif Jun 19 '23 at 07:56
  • Hi @kif , welcome to SO, btw, from where should I pick the `country`? ( Currently I preferred the array `info` ) – Barbaros Özhan Jun 19 '23 at 08:18
  • from the "info" and "location.continent" keys, which means if they are matched, location data of that country should be added to the info where country value is/are matched – kif Jun 19 '23 at 08:21
  • 1
    hi @ozhan, you can you any key as far as the details of object in the location key is added to the object in the info key. if you can see the long and lang in the demo you posted above, its not matched with the input. – kif Jun 19 '23 at 08:38
  • OK @kif just fixed – Barbaros Özhan Jun 19 '23 at 09:08
  • 1
    it works. thanks a lot. – kif Jun 19 '23 at 11:06