Skip to content

Instantly share code, notes, and snippets.

@solex
Created June 17, 2011 17:25
Show Gist options
  • Save solex/1031841 to your computer and use it in GitHub Desktop.
Save solex/1031841 to your computer and use it in GitHub Desktop.
import json
from json.decoder import JSONArray
from json.scanner import py_make_scanner
class UnorderedList(list):
"""
Works like a normal list, except the order of elements doesn't matter on
comparison
>>> UnorderedList([1, 2, 3]) == UnorderedList([3, 1, 2])
True
>>> UnorderedList([1, 2, 3]) == UnorderedList([3, 1, 2, 2])
False
"""
def __eq__(self, other):
if isinstance(other, type(self)):
return sorted(self) == sorted(other)
else:
return False
def __repr__(self):
return "UnorderedList(%s)" % super(UnorderedList, self).__repr__()
def custom_parse_array(*args, **kwargs):
values, end = JSONArray(*args, **kwargs)
return UnorderedList(values), end
class CustomJSONDecoder(json.JSONDecoder):
"""
Custom decoder that reresents JSON arrays as UnorderedLists.
Doesn't use C extensions, so possibly slower than the built-in decoder
>>> json.loads('[1, 2, 3, [4, 5, 6]]', cls=CustomJSONDecoder)
UnorderedList([1, 2, 3, UnorderedList([4, 5, 6])])
>>> l1 = json.loads('[1, 2, 3, [4, 5, 6]]', cls=CustomJSONDecoder)
>>> l2 = json.loads('[1, [6, 5, 4], 3, 2]', cls=CustomJSONDecoder)
>>> l1 == l2
True
>>> l1 = json.loads('[1, 2, 3, [4, 5, 6, 7]]', cls=CustomJSONDecoder)
>>> l2 = json.loads('[1, [6, 5, 4], 3, 2]', cls=CustomJSONDecoder)
>>> l1 == l2
False
>>> l1 = json.loads('{"foo": [1, 2, 3], "bar": 42}', cls=CustomJSONDecoder)
>>> l2 = json.loads('{"foo": [3, 2, 1], "bar": 42}', cls=CustomJSONDecoder)
>>> l1 == l2
True
"""
def __init__(self, *args, **kwargs):
super(CustomJSONDecoder, self).__init__(*args, **kwargs)
self.parse_array = custom_parse_array
self.scan_once = py_make_scanner(self)
if __name__ == '__main__':
import doctest
doctest.testmod()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment