associative arrays: to sort or not to sort?

Mario Kroeplin kroeplin.d at googlemail.com
Tue Jul 20 13:00:15 PDT 2010


> Unless JSON requiers that the keys be in some order,

No, JSON does not require the names of an object to be in alphabetical order.

> the correct solution is to make the check order independent. For example:
> string s = CallReturningJSON();
> s = replace(s,`"a":23.54`, `X`);
> s = replace(s,`"b":0.0012`, `X`);
> s = replace(s,`{"nested":{X,X}}`, `X`);
> s = replace(s,`"goodbye":[true,"or",false,["test",42,X]]`, `X`);
> s = replace(s,`"array":[12,null,{}]`, `Y`);
> s = replace(s,"is\n\ngreat", `Z`);
> s = replace(s,`"json":Z`, `Y`);
> s = replace(s,`"hello":{Y,Y}`, `X`);
> assert(s == `{X,X}`);.

But this is lengthy and seems to lack additional assert checks.

One way out could be to avoid real-world examples in the unittest.
For the simple example of std.json that is only "broken in theory", the correct solution could be:

    assert(s == `{"a":1,"b":null}` || s == `{"b":null,"a":1}`)

But now assume, I want to implement a JSON-RPC encoder that uses std.json.
A JSON-RPC request object has up to four name/value pairs ("jsonrpc", "method", "params", "id").
Instead of only 2!, I now have 4! (too many) possible orders to check in the unittest of the JSON-RPC encoder.

The unspecified order of the foreach iteration does not only affect the unittest of std.json, but also leaks out to far away implementations using std.json.
The same is true for std.xml:

    assert(s == `<tag goodbye="1" hello="0"/>`);

may pass today, but is broken in theory!
You have to notice that XML attributes are stored in an associative array and that toString is implemented using foreach.
Until then, broken unit tests pass...

This is a problem, isn't it?


More information about the Digitalmars-d-learn mailing list