sequentially iterate JSON object. Preserve order for iteration.

1,447 views
Skip to first unread message

David Hall

unread,
Sep 4, 2014, 7:10:58 AM9/4/14
to jansso...@googlegroups.com
Hello!

I have a requirement to iterate a JSON Object but preserve its order, this is so i can complete a hashing function on the information in the object. I have tried the following API calls:

json_object_foreach - This unfortunately does not work for me as, to quote the API Reference "The items are not returned in any particular order."
json_object_iter_next, json_object_iter etc. -  I get the same results as above, and can't seem to find some method to set the order of iteration.

Here is a simplified example of my Array:

{
   
"Data":[
           
{"FirstName": "John", "LastName": "Doe", "Country": "USD", "Email": "te...@email.com"},
           
{"LastName": "Doe", "FirstName": "John", "Email" : "te...@email.com", "Country": "USD"}
       
]
}

I am using the C library.

Thanks,

David.

Jonathan Landis

unread,
Sep 4, 2014, 9:38:09 AM9/4/14
to jansso...@googlegroups.com
On 09/04/2014 04:10 AM, David Hall wrote:
> I have a requirement to iterate a JSON Object but preserve its order,
> this is so i can complete a hashing function on the information in the
> object.

You could dump the object to a string using the JSON_PRESERVE_ORDER or
JSON_SORT_KEYS flags (and probably also the JSON_COMPACT flag), then
hash the string.

JKL

David Hall

unread,
Sep 4, 2014, 10:08:43 AM9/4/14
to jansso...@googlegroups.com
Thank you for your reply and suggestion

Unfortunately i can not hash the entire object, as i require each field to be constructed into a long string before hashing, this is due to supporting other features within the system. So naturally the order in which the data is parsed is important. What i am hoping to find is a function(s) that operate just like the iteration function(s) but allows me to preserve the order. 

David.

Jonathan Landis

unread,
Sep 4, 2014, 12:34:32 PM9/4/14
to jansso...@googlegroups.com

On 09/04/2014 07:08 AM, David Hall wrote:
> I require each field to be constructed into a long string before hashing

So there is some transformation T which you must apply to your object A
before hashing. In that case compute T(A), serialize the result as a
string using JSON_SORT_KEYS and hash that.

Or you could dump the keys into an array, sort the array, and then use
the sorted keys to access the object values in sort order. That is
basically how the ordered serialization works under the hood, and it
uses whatever implementation of qsort() your libc has.

JKL

David Hall

unread,
Sep 5, 2014, 4:23:05 AM9/5/14
to jansso...@googlegroups.com
Yes, that is essentially correct, so the transformation is constructed like this. 

So lets assume we have an array like this:
{
   
"Data":[
 
{"1": "A", "2": "B", "3": "C", "4": "D"},
 
{"2": "B", "1": "A", "4" : "D", "3": "C"}
 
]
}

I am expected to construct a string for each respective object like this:

1.ABCD
2.BADC

The JSON array is constructed by the client, and I have no way of telling which order it is going to be constructed in before i receive the data. When they did the hashing procedure on their end, they hashed it in the order of which they added the data to the object. So, i require the information to be taken out of the object in the order of which i received it, unfortunately due to other constraints simply hashing the entire object is not possible, at least not easily done. It does appear without creating my own function i will be unable to iterate through the object in sequential order. I am curious to know how the Jasson decides on the order of which to store its keys?

Thanks for the help,

David.

Jonathan Landis

unread,
Sep 5, 2014, 2:52:56 PM9/5/14
to jansso...@googlegroups.com
On 09/05/2014 01:23 AM, David Hall wrote:
> It does appear without creating my own function i will be unable to
> iterate through the object in sequential order.

Perhaps not. Have a look at do_dump() in dump.c. The interesting part
starts with the line:

if(flags & JSON_SORT_KEYS || flags & JSON_PRESERVE_ORDER)

Basically you get a list of the keys together with their serial numbers
(the serial numbers tell you the order in which the keys were added),
sort it by serial number, and then iterate using that list of keys.

> I am curious to know how the Jansson decides on the order of which to
> store its keys?

The library uses a hashtable implementation, so it is optimized for fast
key access rather than iteration. In addition, the hash function is
randomized to avoid hash collision attacks.

The people who designed the protocol you are using did not do you any
favors. The Jansson library is not alone in implementing object
iteration the way it does. For example the ECMAScript spec allows
implementation-defined iteration order in for .. in loops.

If they wanted to put things in order, they should have used an array!

JKL

David Hall

unread,
Sep 6, 2014, 5:41:23 AM9/6/14
to jansso...@googlegroups.com
Yes, that is true, thank you for your response. I will come back and reply with an answer if i find one to this problem.

Thanks,

David.

Pardeep Bansal

unread,
Jun 19, 2016, 5:21:20 PM6/19/16
to Jansson users
Hi David,
Did you find any solution with jansson? Unfortunately I have same requirement in which I am getting objects on the basis of priority, and the first object has the highest priority...and so on. I am using C library.
It is my requirement to read the objects in order. I am looking to switch to any other library if jansson doesn't have any solution.

Thanks
Pardeep
Reply all
Reply to author
Forward
0 new messages