Portability problems of ordered hashes

Tom Adam

Developer at Instantiate

http://www.instantiate.co.uk

PHP Arrays

An odd mix of array and hash.

If it is 0 based with sequential integer keys then it is array like, otherwise it is hash like.

However it maintains order, so technically it is an ordered hash.

$array = [
    0 => 'a',
    1 => 'b',
    2 => 'c',
    ...
];
$hash = [
    'a' => 1,
    'b' => 2,
    'c' => 3,
    ...
];
$alsoHash = [
    1 => 'a',
    2 => 'b',
    3 => 'c',
    ...
];

The Ordered Hash

Assume order is important here, keys are not integers,

-> ordered hash

$array = [
    'a' => 1,
    'c' => 2,
    'b' => 3,
    '1' => 4,
    'd' => 5,
];

Then we convert it to JSON for use in an API response

echo json_encode($chart);

{
    "a": 1,
    "c": 2,
    "b": 3,
    "1": 4,
    "d": 5
}

JS Side

In JS this is represented as an object, converting it to a hash.

var obj = {
    'a': 1,
    'c': 2,
    'b': 3,
    1:   4,
    'd': 5
};

An objects keys don't have reliable order

 

Actual order is dependent on browser

for (key in obj) {
    console.log(key, obj[key]);
}

1 4
a 1
c 2
b 3
d 5

JS Side

Ordered sets are in ES6 as Map, but would need a custom "reviver"

// terrible example
var map = new Map();
JSON.parse(theJson, function (k, v) {
    map.set(k,v);
});

Angular causes a further issue as it uses a dictionary sort on the keys of an iterated object, but at least it ensures the same order in all browsers

Other languages

PHP and Ruby (1.9+) preserve hash order when deserialising JSON

 

Python can be made to deserialize to an OrderedDict using a custom hydrator

 

Order preservation is possible in Java with LinkedHashMap and a custom hydrator

Portability problems of ordered hashes

By tomadam

Portability problems of ordered hashes

  • 2,860