# Json Diffing Discussion

**URL:** <https://forum.inductiveautomation.com/t/json-diffing-discussion/96800>\
**Category:** Ignition\
**Created:** [October 2, 2024, 2:11pm UTC](https://forum.inductiveautomation.com/t/json-diffing-discussion/96800 "2024-10-02T14:11:40Z")\
**Posts on this page:** 1\
**Showing post:** 26

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [October 4, 2024, 5:59pm UTC](https://forum.inductiveautomation.com/t/json-diffing-discussion/96800/26 "2024-10-04T17:59:10Z")

</div>

OK. My `ordering()` function was buggy. This is better:

```python
# Human-friendly and git-friendly (deterministically diffable) JSON encoding.

from java.util import TreeMap
from com.inductiveautomation.ignition.common.util import Comparators
from com.inductiveautomation.ignition.common.gson import GsonBuilder

ciAlnumCmp = Comparators.alphaNumeric(False)

# Deep copy with conversion of maps to key-ordered maps and
# conversion of lists-of-dicts that contain a 'name' key into
# ordered lists.
# Keys other than "name" may be supplied, or None to disable
# re-ordering lists of dictionaries.
def ordering(subject, listKey='name'):
	if hasattr(subject, 'items'):
		subst = TreeMap(ciAlnumCmp)
		for k, v in subject.items():
			subst[k] = ordering(v)
		return subst
	if hasattr(subject, ' __iter__'):
		# Use a generator to exit quickly if any element of the
		# list-like object is *not* a dictionary-like object.
		if listKey and all(hasattr(inner, 'items') for inner in subject):
			reordered = TreeMap(ciAlnumCmp)
			reordered.update([(x.get(listKey, str(i)), ordering(x)) for (i, x) in enumerate(subject)])
			return reordered.values()
		return [ordering(x) for x in subject]
	return subject
#

#
def orderedJson(source):
	json = system.util.jsonDecode(source)
	ordered = ordering(json)
	gson = GsonBuilder().setPrettyPrinting().create()
	return gson.toJson(ordered)
#

def test():
	original = {'a8': 0.9, 'a9': 1, 'A10': 1.1, 'A12':1.2, 'a11': [4, 5, 6]}
	ordered = jsonUtil.ordering(original)
	print "Ordered:"
	print repr(ordered)
	print "Using system.util.jsonEncode():"
	print system.util.jsonEncode(dict(_=ordered), 2)[6:-1]
	print "Using Gson:"
	gson = GsonBuilder().setPrettyPrinting().create()
	print gson.toJson(ordered)
#

```

Running `someScript.test()` in the script console yields this:

```python
Ordered:
{u'a8': 0.9, u'a9': 1, u'A10': 1.1, u'a11': [4, 5, 6], u'A12': 1.2}
Using system.util.jsonEncode():
{
  "A10": 1.1,
  "A12": 1.2,
  "a11": [
    4,
    5,
    6
  ],
  "a8": 0.9,
  "a9": 1
}
Using Gson:
{
  "a8": 0.9,
  "a9": 1,
  "A10": 1.1,
  "a11": [
    4,
    5,
    6
  ],
  "A12": 1.2
}
>>>

```

Much better.

Also lets you disable list re-ordering, or use a different key.

---

_[View the full topic](https://forum.inductiveautomation.com/t/json-diffing-discussion/96800)._
