Swift 4: Keeping the same order when parsing a JSON - json

I need to show a list of addresses in my app while keeping the same order as the response JSON. It looks something like this:
{
"addresses": {
"e5fdb5ba-7afb-11e8-bead-43321d1a8905": {
"contact": "Name1",
"zipCode": "06100"
},
"1495b580-7afc-11e8-bead-9f4049791561": {
"contact": "Name2",
"zipCode": "06100"
},
"e5fdb5ba-7afb-11e8-bead-43321d1a8905": {
"contact": "Name3",
"zipCode": "06100"
},
"1495b580-7afc-11e8-bead-9f4049791561": {
"contact": "Name4",
"zipCode": "06100"
}
}
}
But when I parse the response using
JSONSerialization.jsonObject(with: data, options: [])
The order of the addresses gets all mixed up. Is there a way to keep the exact same order as the JSON?

as rmaddy says in their comment, the JSON you posted is a dictionary. Dictionaries are inherently unordered, so the order you get from the back-end is not guaranteed either. Some server implementations may give a consistent order and some may not.
If you want a certain order you will need to change the back-end system to use an array rather than a dictionary.
If you have no control of the client side and still want to preserve the order of the keys from the JSON, you will probably have to parse the JSON yourself manually, build an array of the keys, and then use those keys to fetch the items from the dictionary in that order.

If the order of your data is important you should put it into an Array, not a Dictionary (which is inherently without order but with quick keyed access as others have noticed). Please change your backend accordingly and ask another question if it does not work.

Related

Split a JSON string value using JMESPath

I have a payload in a format similar to below:
{
"year": "2022",
"cycle": "Aug",
"origin": {
"file_location": "GDT Post-Distribution Manifest/Italy/Rome/2022/Aug/Italy Rome_202208241528.xlsx",
"protocol": "s3:"
}
}
I want to check if the third element of the file_location is equal to something (in this case it is marked as Rome).
How do I gain access this element?
In order to achieve this, you would need to have some sort of functionality to split a string, which is, sadly, not something that exists in the language for the moment being.
There is a proposal to add the functionality, though: New function: array[string] split(string $separator, string $subject).

Can we write json key with space like(first name)

Can we write json key with space like first name?
Below is the sample json:
[
{
"first_name": "James"
},
{
"first_name": "Tom"
}
]
Yes, you can, it is valid RFC 8259, however it will make more difficult to use in some languages, for example in PHP you want be able to use the arrow operator to access the data.
This obviously won't make this JSON not valid.

Order of performing sorting on a big JSON object

i have a big json object with a list of "tickets". schema looks like below
{
"Artist": "Artist1",
"Tickets": [
{
"Id": 1,
"Attr2Array": [
{
"Att41": 1,
"Att42": "A",
"Att43": null
},
{
"Att41": 1,
"Att42": "A",
"Att43": null
},
],
.
.
.
(more properties)
"Price": "20",
"Description": "I m a ticket"
},
{
"Id": 4,
"Attr2Array": [
{
"Att41": 1,
"Att42": "A",
"Att43": null
},
{
"Att41": 1,
"Att42": "A",
"Att43": null
},
],
.
.
.
.
(more properties)
"Price": "30",
"Description": "I m a ticket"
}
]
}
each item in the list has around 25-30 properties (some simple types, and others complex array as nested objects)
i have to read the object from an api endpoint and extract only "ID" and "Description" but they need to be sorted by "Price" which is an int for example
In what order shall i proceed with this data manipulation
Shall i use the json object, deserialised it into another object with just those 2 properties (which i need) and THEN perform sort "asc" on the "Price"?
Please note that after i have the sorted list i will have to convert it back to a json list because the front end consumes a json after all.
What i dont like about this approach is the cycle of serialisation and deserialisation that happens
or
I perform a sort on the json object first (using for example a binary/bubble sort) and then use the object to create a strongly typed (deserialised) object with just those 2 properties and then serialise it back to pass to the front end
I dont know how performant the bubble sort will be and if at all i will get any gain in performance for large chunks of data processing.
I also need to keep in mind that this implementation can take into account other properties like "availabilitydate" because at a later date, this front end could add one more filter like "availabilitdate" asc
any help is much appreciated
thanks
You can deserialize your JSON string (or file) using the Microsoft System.Web.Extensions and JavaScriptSerializer.DeserializeObject.
First, you must have classes associated to your JSON. To create classes, select your JSON sample data and, in Visual Studio, go to Edit / Paste Special / Paste JSON As Classes.
Next, use this sample to deserialize a JSON string to typed objects, and to sort all Tickets by Price property using Linq.
String json = System.IO.File.ReadAllText(#"C:\Data.json");
var root = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<Rootobject>(json);
var sortedTickets = root.Tickets.OrderBy(t => t.Price);

JSON Reference to non-object value

We are currently investigating JSON as a potential API data transfer language for our system and a question about using JSON Reference came up.
Consider the following example:
{
"invoice-address" : { "street": "John Street", "zip": "12345", "city": "Someville" },
"shipping-address": { "$ref": "#/invoice-address" }
}
According to our research, this is a valid usage of JSON Reference. We replace the instance of an object with another object containing the reference pointing to a different object using a JSON Pointer fragment.
Now, a JSON Reference always consists of a key-value pair and thus has to be enclosed in an object. This would mean that in order to reference a non-object data type (e.g. the zip and city strings in the example above) you would have to do the following:
{
"invoice-address" : { "street": "John Street", "zip": "12345", "city": "Someville" },
"shipping-address": { "street": "Doe Street", "zip": { "$ref": "#/invoice-address/zip" }, "city": { "$ref": "#/invoice-address/city" } }
}
Even though the JSON Pointers now correctly point to string values, we had to change the data type of zip and city from string to object, which make them fail validation against our JSON Schema, because it declares them as strings.
However, the JSON Reference draft states:
Implementations MAY choose to replace the reference with the referenced value.
Does that mean that we are allowed to "preprocess" the file and replace the JSON Reference object with the resolved string value before validating against the JSON Schema? Or are references limited to object types only?
Thanks to anyone who can shed some light onto this.
I wouldn't expect most validators to resolve JSON References before validation. You could either:
resolve JSON References before validation
adapt the JSON Schemas to allow for JSON Reference objects in certain places
Personally, I think the first option is much neater.
You could end up with circular references I suppose - I don't know which validator/language you're using, but tv4 can definitely handle it.

How to deserialize json with nested Dictionaries?

For some endpoints SimpleGeo.com returns something like this:
{
"geometry":{
"type":"Point",
"coordinates":[
-122.421583,
37.795027
]
},
"type":"Feature",
"id":SG_5JkVsYK82eLj26eomFrI7S_37.795027_-122.421583#1291796505,
"properties":{
"province":"CA",
"city":"San Francisco",
"name":"Bell Tower",
"tags":[],
"country":"US",
"phone":"+1 415 567 9596",
"href": http://api.simplegeo.com/1.0/features/SG_5JkVsYK82eLj26eomFrI7S_37.795027_-122.421583#1291796505.json,
"address":"1900 Polk St",
"owner":"simplegeo",
"postcode":"94109",
"classifiers":[
{
"category":"Restaurant",
"type":"Food & Drink",
"subcategory":""
}
]
}
}
(see http://simplegeo.com/docs/api-endpoints/simplegeo-features#get-detailed-information).
Now I have a small problem deserializing the 'properties' part. If I use e.g. a type of Dictionary it converts it to a nice dictionary, but the 'classifiers' value is just one {} string.
Is there any way to tell json.net to deserialize sub-arrays into yet another Dictionary etc etc? Basically there's an amount of plain key/values in that return, but I do know that there might be more than just that 'classifiers' sub-array (see the 'tags'), and maybe the depth goes even further in the values...
So basically what I was wondering is, how do I properly deserialize the properties part? Any suggestions? I don't mind writing my own JsonConverter, but maybe there is already a way that works without it.
I've found a solution for a similar question over here:
Json.NET: Deserializing nested dictionaries.
It uses a custom JsonConverter and I don't see a way to do without it.