I have been trying to iterate in a JSON that contains a map within a map for hours with no luck...
This is the JSON string:
{
"P31": {
"wikibase-entityid": "Q16603799"
},
"P227": {
"string": "1084653095"
},
"P1001": {
"wikibase-entityid": "Q183"
},
"P1448": {
"monolingualtext": "Verordnung über Sicherheit und Gesundheitsschutz bei der Verwendung von Arbeitsmitteln"
},
"P1813": {
"monolingualtext": "Betriebssicherheitsverordnung"
},
"P7677": {
"string": "betrsichv_2015"
},
"P580": {
"time": "+2002-10-03T00:00:00Z"
},
"P2671": {
"string": "/g/1224z0c0"
},
"P9696": {
"string": "11477"
}
}
Image for an easy visual reference:

Note: each property can have multiple values.
I basically want to create a loop inside which I've got access to the property (PXXX, first thing), the type of the property (key in the inner map) and the value of the property (value in the inner map).
I have tried to convert the string to a Map using "new Map(JSON.parse(jsonStr))", "new Map(Object.entries(jsonStr))" and other with no luck.
Additionally, I tried to iterate inside it with a "for (var key in obj)" and with a "myMap.forEach((value_propertyInfo, key_propertyName) => {...}" without luck either.
Some times it looks like I am iterating char by char, while others simply throw an error saying that the map is not iterable.
Does anybody know what I should use instead?
Thanks!
Don't bother with Map. Just iterate over the data object, log the key, and then log over that property's object entries, and log the key, and the value.
const data = {"P31":{"wikibase-entityid":"Q16603799"},"P227":{"string":"1084653095"},"P1001":{"wikibase-entityid":"Q183"},"P1448":{"monolingualtext":"Verordnung über Sicherheit und Gesundheitsschutz bei der Verwendung von Arbeitsmitteln"},"P1813":{"monolingualtext":"Betriebssicherheitsverordnung"},"P7677":{"string":"betrsichv_2015"},"P580":{"time":"+2002-10-03T00:00:00Z"},"P2671":{"string":"/g/1224z0c0"},"P9696":{"string":"11477"}};
for (const key in data) {
console.log(key);
const entries = Object.entries(data[key]);
for (const [key, value] of entries) {
console.log(key, value);
}
}
The data structure is really suboptimal. It uses variable property names, "PXXX" in the outer and the type in the inner objects. Ideally you have always fixed property names and only the values vary. The best would be this form of array and iteration
a=[
[prop, type, value],
[prop, type, value], // {"prop": prop, "type": type, "value":value} is also good
...
]
for(const [prop, type, value] of a) handleProperty(prop, type, value);
We can nearly reach this by transforming the json string before parsing:
s='{"P31":{"wikibase-entityid":"Q16603799"},"P227":{"string":"1084653095"},"P1001":{"wikibase-entityid":"Q183"},"P1448":{"monolingualtext":"Verordnung über Sicherheit und Gesundheitsschutz bei der Verwendung von Arbeitsmitteln"},"P1813":{"monolingualtext":"Betriebssicherheitsverordnung"},"P7677":{"string":"betrsichv_2015"},"P580":{"time":"+2002-10-03T00:00:00Z"},"P2671":{"string":"/g/1224z0c0"},"P9696":{"string":"11477"}}'
data=JSON.parse(s.replaceAll(':{',':[').replaceAll('":"','","').replaceAll('"}','"]'))
/* We now have
data={
prop:[type, value],
prop:[type, value],
...
}*/
for(const [prop,[type, value]] of Object.entries(data)) console.log(prop,type,value)
using Object.entries() and destructuring assignment.
If you don't want to transform the JSON string, you will have to use
You can loop through the object properties and extract for each item propertyId, propertyName and propertyValue like this:
let o = //the object coming from the json
Object.keys(o).forEach( (propertyId) => {
//I'm taking for granted that each item will contain one property only and that property will be what we are looking for
let propertyType = Object.keys( o[propertyId] )[0];
let propertyValue = o[propertyId][propertyType];
});