Related
[
{
"id": 0.5256669517010202,
"color": false,
"selected": false,
"name": "",
"type": "",
"label": "",
"fieldName": "",
"required": "",
"validation": ""
},
{
"id": 0.5901705709044824,
"color": false,
"selected": false,
"type": [
{
"id": 0.30332161644408817,
"color": true,
"selected": false,
"name": "",
"type": "",
"label": "",
"fieldName": "",
"required": "",
"validation": ""
},
{
"id": 0.5423422175390649,
"color": true,
"selected": false,
"name": "",
"type": "",
"label": "",
"fieldName": "",
"required": "",
"validation": ""
},
{
"id": 0.959208393000617,
"color": true,
"selected": false,
"name": "",
"type": "",
"label": "",
"fieldName": "",
"required": "",
"validation": ""
}
],
"label": "",
"fieldName": "",
"required": "",
"validation": ""
},
{
"id": 0.5933110602496239,
"color": false,
"selected": false,
"type": "",
"label": "",
"fieldName": "",
"required": "",
"validation": ""
}
]
I think you should use Map method
const data = [
{
"id": 0.5256669517010202,
"color": false,
"selected": false,
"name": "",
"type": "",
"label": "",
"fieldName": "",
"required": "",
"validation": ""
},
{
"id": 0.5901705709044824,
"color": false,
"selected": false,
"type": [
{
"id": 0.30332161644408817,
"color": true,
"selected": false,
"name": "",
"type": "",
"label": "",
"fieldName": "",
"required": "",
"validation": ""
},
{
"id": 0.5423422175390649,
"color": true,
"selected": false,
"name": "",
"type": "",
"label": "",
"fieldName": "",
"required": "",
"validation": ""
},
{
"id": 0.959208393000617,
"color": true,
"selected": false,
"name": "",
"type": "",
"label": "",
"fieldName": "",
"required": "",
"validation": ""
}
],
"label": "",
"fieldName": "",
"required": "",
"validation": ""
},
{
"id": 0.5933110602496239,
"color": false,
"selected": false,
"type": "",
"label": "",
"fieldName": "",
"required": "",
"validation": ""
}
]
data.map((item) => item.id)
Just Try!
You should declared attribute type as Array always!
data.map(Item => (
Item.type.map(Item => ())
))
the map method is suitable here. For example you have your all data within state or another variable, well you can map throw it:
<div>
{yourData?.length && yourData.map(item => {
return(
<span>{item.id}</span>
...
<div>{item.type.map(typeItem => {
return(
<span>{typeItem.id}</span>
...
)
})
)})}
</div>
We have the following JSON structure from an TSheets API which has an actual timesheet 'id' as an object in the hierarchy. This means there's no fixed hierarchy structure and we need to dynamically find a way to loop through each timesheet.
We've stored this data in a variant column, but want to flatten it and have a row per timesheet. Is there a way to list all objects under results.timesheets to retrieve all ids in a single column (i.e. '13510958','13510960') so we can loop through these to obtain the lower level details. Seems like an odd way to construct an API response!
JSON can be found below:
{
"results": {
"timesheets": {
"13510958": {
"id": 13510958,
"user_id": 1360082,
"jobcode_id": 16297998,
"start": "",
"end": "",
"duration": 28800,
"date": "2021-03-29",
"tz": 1,
"tz_str": "Europe/London",
"type": "manual",
"location": "QuickBooks Time web",
"on_the_clock": false,
"locked": 0,
"notes": "",
"customfields": {
"802478": "",
"650642": "",
"650640": "Consulting Services:Services"
},
"last_modified": "2021-04-19T14:34:16+00:00",
"attached_files": [],
"created_by_user_id": 1360067
},
"13510960": {
"id": 13510960,
"user_id": 1360082,
"jobcode_id": 16297998,
"start": "",
"end": "",
"duration": 28800,
"date": "2021-03-30",
"tz": 1,
"tz_str": "Europe/London",
"type": "manual",
"location": "QuickBooks Time web",
"on_the_clock": false,
"locked": 0,
"notes": "",
"customfields": {
"802478": "",
"650642": "",
"650640": "Consulting Services:Services"
},
"last_modified": "2021-04-19T14:34:16+00:00",
"attached_files": [],
"created_by_user_id": 1360067
}}
} }
You can use LATERL FLATTEN, LISTAGG or ARRAY_AGG to get it:
with json_data as ( select parse_json('{
"results": {
"timesheets": {
"13510958": {
"id": 13510958,
"user_id": 1360082,
"jobcode_id": 16297998,
"start": "",
"end": "",
"duration": 28800,
"date": "2021-03-29",
"tz": 1,
"tz_str": "Europe/London",
"type": "manual",
"location": "QuickBooks Time web",
"on_the_clock": false,
"locked": 0,
"notes": "",
"customfields": {
"802478": "",
"650642": "",
"650640": "Consulting Services:Services"
},
"last_modified": "2021-04-19T14:34:16+00:00",
"attached_files": [],
"created_by_user_id": 1360067
},
"13510960": {
"id": 13510960,
"user_id": 1360082,
"jobcode_id": 16297998,
"start": "",
"end": "",
"duration": 28800,
"date": "2021-03-30",
"tz": 1,
"tz_str": "Europe/London",
"type": "manual",
"location": "QuickBooks Time web",
"on_the_clock": false,
"locked": 0,
"notes": "",
"customfields": {
"802478": "",
"650642": "",
"650640": "Consulting Services:Services"
},
"last_modified": "2021-04-19T14:34:16+00:00",
"attached_files": [],
"created_by_user_id": 1360067
}}
}}') raw )
select listagg( v.key , ',' ), array_agg( v.key)
from json_data,
lateral flatten( raw:results.timesheets ) v;
When you want to obtain the lower level details without looping through them, you can also access them directly. For example the timesheet, user_id and duration:
with json_data as (
select parse_json('{
"results": {
"timesheets": {
"13510958": {
"id": 13510958,
"user_id": 1360082,
"jobcode_id": 16297998,
"start": "",
"end": "",
"duration": 28800,
"date": "2021-03-29",
"tz": 1,
"tz_str": "Europe/London",
"type": "manual",
"location": "QuickBooks Time web",
"on_the_clock": false,
"locked": 0,
"notes": "",
"customfields": {
"802478": "",
"650642": "",
"650640": "Consulting Services:Services"
},
"last_modified": "2021-04-19T14:34:16+00:00",
"attached_files": [],
"created_by_user_id": 1360067
},
"13510960": {
"id": 13510960,
"user_id": 1360082,
"jobcode_id": 16297998,
"start": "",
"end": "",
"duration": 28800,
"date": "2021-03-30",
"tz": 1,
"tz_str": "Europe/London",
"type": "manual",
"location": "QuickBooks Time web",
"on_the_clock": false,
"locked": 0,
"notes": "",
"customfields": {
"802478": "",
"650642": "",
"650640": "Consulting Services:Services"
},
"last_modified": "2021-04-19T14:34:16+00:00",
"attached_files": [],
"created_by_user_id": 1360067
}}
}}') raw )
select key, value:user_id, value:duration
from json_data,
lateral flatten(input=>raw:results.timesheets)
I was able to get this to work.
SELECT VALUE AS TIMESHEET_JSON, TIMESHEET_JSON:id AS ID
FROM TABLE(FLATTEN(INPUT=> PARSE_JSON('{Your JSON Here}'):results.timesheets));
You may need to do a little more work to get your JSON into the flatten. A lateral flatten may be useful. This worked once I put your JSON into a one column cte.
SELECT VALUE AS TIMESHEET_JSON, TIMESHEET_JSON:id AS ID
FROM cte
,LATERAL FLATTEN(INPUT=> PARSE_JSON(JSON):results.timesheets);
You can then use typical JSON parsing syntax against the VALUE column for getting at your individual attributes per record.
I have the following MongoDB objects which I have first transformed into key-value k-v pairs using $objectToArray and $split. How do I remove the empty string "" from the value v array? Thanks!
{
"_id" : ObjectId("5e9ecf782980434d78120a49"),
"data_kv" : [ { "k" : "U1", "v" : [ "", "", "University", "", "", "of", "", "", "Australia", "", "" ] } ]
}
{
"_id" : ObjectId("5e9ecf7f2980434d78120a4a"),
"data_kv" : [ { "k" : "U2", "v" : [ "", "", "University", "of", "", "", "", "", "Australia", "", "" ] } ]
}
{
"_id" : ObjectId("5e9ecf8a2980434d78120a4b"),
"data_kv" : [ { "k" : "U3", "v" : [ "", "", "University", "", "", "of", "", "", "", "Sweden", "", "" ] } ]
}
You can use below aggregation
db.collection.aggregate([
{ $project: {
data_kv: {
$map: {
input: "$data_kv",
as: "kv",
in: {
k: "$$kv.k",
v: {
$filter: {
input: "$$kv.v",
cond: { $ne: ["$$this", ""] }
}
}
}
}
}
}}
])
MongoPlayground
I just started using JSONata and I found it quite fascinating to parse JSON easily. But I have this problem, and I'm not sure if it can be done with JSONata directly.
I want to include a counter that goes from 1 to "the number of objects in an array", like so:
Original output from JSONata expression:
[
{
"a": false,
"b": "",
"c": "",
"d": true
},
{
"a": false,
"b": "",
"c": "",
"d": true
},
{
"a": false,
"b": "",
"c": "",
"d": true
}
]
Wanted output:
[
{
"count": "1",
"a": false,
"b": "",
"c": "",
"d": true
},
{
"count": "2",
"a": false,
"b": "",
"c": "",
"d": true
},
{
"count": "3",
"a": false,
"b": "",
"c": "",
"d": true
}
]
Is it possible? Thank you in advance.
You can use the $map() function to iterate over a list and apply an expression to each item. The second argument of your function will be the index within the array. So for your example, the following will merge the count property into your original array of objects:
$ ~> $map(function($v, $i) {
$merge([{'count': $i+1}, $v])
})
See this working in the JSONata Exerciser: http://try.jsonata.org/rkDpyXMVM
I want to have the JSON below as an array with duplicated key values, i.e.:
"2016-09-16":{"available":"1","bind":0,"info":"","notes":"","price":"","promo":"","status":"booked"}
twice. How can I do that?
{
"2016-06-28": {
"available": "1",
"bind": 0,
"info": "",
"notes": "",
"price": "",
"promo": "",
"status": "booked"
},
"2016-06-29": {
"available": "1",
"bind": 0,
"info": "",
"notes": "",
"price": "",
"promo": "",
"status": "booked"
},
"2016-06-30": {
"available": "1",
"bind": 0,
"info": "",
"notes": "",
"price": "",
"promo": "",
"status": "booked"
},
"2016-07-04": {
"available": "1",
"bind": 0,
"info": "",
"notes": "",
"price": "",
"promo": "",
"status": "booked"
},
"2016-07-05": {
"available": "1",
"bind": 0,
"info": "",
"notes": "",
"price": "",
"promo": "",
"status": "booked"
},
"2016-07-06": {
"available": "1",
"bind": 0,
"info": "",
"notes": "",
"price": "",
"promo": "",
"status": "booked"
},
"2016-07-07": {
"available": "1",
"bind": 0,
"info": "",
"notes": "",
"price": "",
"promo": "",
"status": "booked"
},
"2016-09-16": {
"available": "1",
"bind": 0,
"info": "",
"notes": "",
"price": "",
"promo": "",
"status": "booked"
},
"2016-09-15": {
"available": "1",
"bind": 0,
"info": "",
"notes": "",
"price": "",
"promo": "",
"status": "booked"
},
"2016-09-14": {
"available": "1",
"bind": 0,
"info": "",
"notes": "",
"price": "",
"promo": "",
"status": "booked"
},
"2016-09-13": {
"available": "1",
"bind": 0,
"info": "",
"notes": "",
"price": "",
"promo": "",
"status": "booked"
},
"2016-09-16": {
"available": "1",
"bind": 0,
"info": "",
"notes": "",
"price": "",
"promo": "",
"status": "booked"
},
"2016-09-17": {
"available": "1",
"bind": 0,
"info": "",
"notes": "",
"price": "",
"promo": "",
"status": "booked"
}
}
JSON with duplicate keys in the same object is not reliable across JSON parsers (some will choke, some will give you only the value of the last occurrence) and not useful in any case. Use arrays of objects for the values of those date keys, not individual objects:
{
"2016-06-29": [{
"available": "1",
"bind": 0,
"info": "",
"notes": "",
"price": "",
"promo": "",
"status": "booked"
}],
"2016-09-16": [{
"available": "1",
"bind": 0,
"info": "",
"notes": "",
"price": "",
"promo": "",
"status": "booked"
}, {
"available": "1",
"bind": 0,
"info": "",
"notes": "",
"price": "",
"promo": "",
"status": "booked"
}],
"2016-09-15": [{
"available": "1",
"bind": 0,
"info": "",
"notes": "",
"price": "",
"promo": "",
"status": "booked"
}]
}
(Data shortened for clarity.)
In the above, note how 2016-06-29 and 2016-09-15 have arrays with just one entry, but 2016-09-16 has an array with two entries.