JSONata combine array of arrays in a 1:1 mapping

So we have an array of array with objects

[
[{
  "time" : "now"
},
{
  "time" : "yesterday"
}
],
[
  {
    "Temperature" : 10
  },
  {
    "Temperature" : 12
  }
]
]

Now I want to merge these arrays that it looks like

[{
  "time" : "now",
  "Temperature": 10
},
{
  "time" : "yesterday",
  "Temperature" : 12
}
]

So basically they're merged 1:1. First element gets combined with first element, second with second an so one.

I've tried merge. That reduces to one array level, but doesn't merge them as intended

Then I've tried with $map function but didn't work as expected, too

$map($, function($v,$i,$a)
{
{
  "time": $v.time[$i],
  "Temperatur" : $v.Temperature[$i]
}   
}
)

I think there should be a much easier way than using explicitly a $map function. Hope you can help me.

You can try at https://try.jsonata.org/XQQJfQ3hv

It it is easer I also have the data in format

[
  [
    "now",
    "yesterday"
  ],
  [
    10,
    12
  ]
]

The following jsonata query does the job for https://try.jsonata.org/XQQJfQ3hv

$zip($[0],$[1]).$merge($)

see https://docs.jsonata.org/array-functions#zip

UPDATE - I have corrected query above

5 Likes

Something like this (assuming that the input is payload)

$map(payload[0], function($v, $i, $a) {
   $a[$i].time &': ' & payload[1][$i].Temperature
})

Produces output:

[
  "now: 10",
  "yesterday: 12"
]

It is not what you want, then again, you have a strange array of objects, how did you get this data ?

Easier is with a function node (pretty sure it can be done with JSONata, but for me this is quicker)

let m = msg.payload
let out = []
for(x=0;x<m.length;x++){
    out.push(
        {
            "time":m[0][x].time,
            "Temperature":m[1][x].Temperature,
            
        })
}

return {payload:out}

Output

[
  {
    "time": "now",
    "Temperature": 10
  },
  {
    "time": "yesterday",
    "Temperature": 12
  }
]

edit I just see the post from @janvda - fantastic stuff!

assuming that the data is in msg.payload, wouldn't you need $zip(payload[0],payload[1]).$merge($)?

For the flow in NodeRED yes. However to keep this example as simple as possible I omitted the payload thing. My real example is much more complex and nested deeply below payload.

If anyone is interested thats the whole flow

JSONata expression is:

$zip(
    [
(**.'dwd:TimeStep').{
    "time" : $toMillis($) / 1000
}],
[    
$split($trim( (**.'dwd:Forecast'['$'.'dwd:elementName' = "TTT"].'dwd:value')[0] )," ").{
     "Temperatur": $round(($number($) - 273.15)*100)/100
                        }
]).$merge($).[
    $,
    {
        "Ort" : "Bremerhaven"
    }
]

It fetches the Weatherforceast from german weather service (DWD), here only the Temperature and stores it in influxdb.
Interessting point: In NodeRED you need the expression

$round(($number($) - 273.15)*100)/100

Without rounding values like "23.900000000000034" are printed. I know thats because about the floating point representation. Still under try.jsonata.org there seems to be an automatically rounding. Testing the data there leads always to values like "23.90"

Here is the complete flow if anybody is interested

[{"id":"7611bdf9.379454","type":"subflow","name":"InfluxDB out","info":"","category":"","in":[{"x":-20,"y":80,"wires":[{"id":"b3ed248c.c05218"}]}],"out":[],"env":[],"color":"#DDAA99"},{"id":"b3ed248c.c05218","type":"influxdb out","z":"7611bdf9.379454","influxdb":"52cc6f72.aa656","name":"","measurement":"","precision":"","retentionPolicy":"","x":200,"y":80,"wires":[]},{"id":"52cc6f72.aa656","type":"influxdb","z":"","hostname":"192.168.0.5","port":"8086","protocol":"http","database":"my_db","name":"","usetls":false,"tls":"b0b9273e.9f1208"},{"id":"b0b9273e.9f1208","type":"tls-config","z":"","name":"","cert":"","key":"","ca":"","certname":"m2mqtt_srv.crt","keyname":"m2mqtt_srv.key","caname":"m2mqtt_ca.crt","verifyservercert":false},{"id":"6f968d9a.5b17c4","type":"inject","z":"7f2f6783.e36db8","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":120,"y":2080,"wires":[["1baf3831.992eb8"]]},{"id":"1baf3831.992eb8","type":"http request","z":"7f2f6783.e36db8","name":"","method":"GET","ret":"bin","paytoqs":false,"url":"https://opendata.dwd.de/weather/local_forecasts/mos/MOSMIX_L/single_stations/10129/kml/MOSMIX_L_LATEST_10129.kmz","tls":"","persist":false,"proxy":"","authType":"","x":310,"y":2080,"wires":[["ae8c3db5.bcd7c"]]},{"id":"ae8c3db5.bcd7c","type":"zip","z":"7f2f6783.e36db8","name":"","mode":"decompress","filename":"","outasstring":true,"x":490,"y":2080,"wires":[["741ecb83.070aa4"]]},{"id":"741ecb83.070aa4","type":"change","z":"7f2f6783.e36db8","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload[0].payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":690,"y":2080,"wires":[["e5997c7e.3234b"]]},{"id":"e5997c7e.3234b","type":"xml","z":"7f2f6783.e36db8","name":"","property":"payload","attr":"","chr":"","x":870,"y":2080,"wires":[["dbc9a294.c0f18"]]},{"id":"dbc9a294.c0f18","type":"change","z":"7f2f6783.e36db8","name":"Komplexes Aufbereiten für Influx","rules":[{"t":"set","p":"payload","pt":"msg","to":"$zip(\t    [\t(**.'dwd:TimeStep').{\t    \"time\" : $toMillis($) / 1000\t}],\t[    \t$split($trim( (**.'dwd:Forecast'['$'.'dwd:elementName' = \"TTT\"].'dwd:value')[0] ),\" \").{\t     \"Temperatur\": $round(($number($) - 273.15)*100)/100\t                        }\t]).$merge($).[\t    $,\t    {\t        \"Ort\" : \"Bremerhaven\"\t    }\t]","tot":"jsonata"},{"t":"set","p":"measurement","pt":"msg","to":"Wettervorhersage","tot":"str"},{"t":"set","p":"precision","pt":"msg","to":"s","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1090,"y":2080,"wires":[["d5d64173.600fe","4e027183.4d9d5"]]},{"id":"d5d64173.600fe","type":"subflow:7611bdf9.379454","z":"7f2f6783.e36db8","name":"","x":1350,"y":2080,"wires":[]},{"id":"4e027183.4d9d5","type":"debug","z":"7f2f6783.e36db8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1260,"y":2020,"wires":[]}]

A weatherstation list can be obtained here https://www.dwd.de/DE/leistungen/met_verfahren_mosmix/mosmix_stationskatalog.cfg?view=nasPublication&nn=16102

There you get the station number, which can be "inserted" here https://opendata.dwd.de/weather/local_forecasts/mos/MOSMIX_L/single_stations/

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.