The code that generates the JSON objects in that way was yours. It generated separate objects because you used an empty string as a target for the JSONSetElement output.
If you want to combine all the records into a single object you can do that by using a variable as the target for the JSONSetElement output. That allows you to use the name as the key in the key/value pair. Each time through the loop, a new key/value would be entered in the object stored by the variable.
As for getting data out of the JSON. If you approach the problem as someone who knows everything about the data, then it is easiest to use the names as keys and then to say JSONGetElement ( json ; "Mint Chocolate Chip.Brand" )
.
However, when you don't know anything about the current data set, you will not know in advance that the key is "Mint Chocolate Chip." In that case, you have to iterate over the set of data by getting the keys, then looping through them. In this situation, there is little or no disadvantage in having an array of objects because the effort required and methods used are almost identical.
/*
field "JSON" contains an object, that contains key/value pairs
{
"Mint Chocolate Chip" :
{
"Brand" : "Tillamook",
"Cost" : "9.45",
"FinanceCode" : "MCC",
"NickName" : "Mint"
},
"Strawberry" :
{
"Brand" : "Tillamook",
"Cost" : "9.45",
"FinanceCode" : "Stra",
"NickName" : "Strawberry"
}
}
*/
Let ( json = IceCream::JSON ; JSONGetElement ( json ; "Mint Chocolate Chip.Brand" ) )
// Output is "Tillamook"
/*
field "JSON" contains an array of objects, the objects contain key/value pairs
[
{
"Mint Chocolate Chip" :
{
"Brand" : "Tillamook",
"Cost" : "9.45",
"FinanceCode" : "MCC",
"NickName" : "Mint"
}
},
{
"Strawberry" :
{
"Brand" : "Tillamook",
"Cost" : "9.45",
"FinanceCode" : "Stra",
"NickName" : "Strawberry"
}
}
]
*/
Let ( json = IceCream::JSON ; JSONGetElement ( json ; "[0].Mint Chocolate Chip.Brand" ) )
// Output is "Tillamook"