Turning Sets Into Arrays Before JSON
In this lesson, you added order 1042’s tags to the JavaScript label, found out why the Python script sorts them, and saw what JavaScript writes when you hand it a Set.
- The Python script builds a set from the order’s tags, which drops the repeated
"gift", and putssorted(tags)in the label, not the set. That’s becausejson.dumps()would refuse the set, withTypeError: Object of type set is not JSON serializable, and because a Python set has no fixed order, so the same tags can come out either way round from one run to the next. Sorted, the tags come out in the same order every time. - Python’s
sorted()ports as.toSorted(), buttags.toSorted()stops withTypeError: tags.toSorted is not a function..toSorted()is an array method, and a Set isn’t an array. - A JavaScript Set keeps its items in the order they arrived, so the sort looks unneeded, and if
JSON couldn’t take a Set, surely JavaScript would say so, as Python does. So it’s tempting to
pass the Set itself.
JSON.stringify()then writes"tags": {}, with no error, and the courier’s form would get no tags. - JSON has no set type. It knows six kinds of value: objects, arrays, strings, numbers, booleans
(
trueandfalse), andnull.JSON.stringify()treats a Set like any other object and writes out its properties, and a Set keeps its items inside, not as properties, so there’s nothing to write. A Map comes out empty the same way. - Python’s
json.dumps()refuses a set, butJSON.stringify()writes a Set, or a Map, as an empty object, and says nothing. - The fix is to convert the Set to an array first:
[...tags]spreads its items into a new array, like Python’s[*tags], and.toSorted()sorts it, giving["fragile", "gift"]. Python’ssorted()makes the list for you, but.toSorted()needs an array, so in JavaScript it’s two steps. - The sort is worth keeping in JavaScript too. A Set keeps the order the shop sent the tags in, so
if the next order lists
"fragile"first, the Set puts"fragile"first. Sorted, they read the same on every label, and the label matches the Python script’s. - Watch out for other values JSON doesn’t know. A phone read as
order.customer?.phone, with no??, isundefinedfor order 1042, and JavaScript drops the key altogether, where Python’sNoneprintsnull. Dates turn into text.
Here’s the end of the Python script. Higher up, it parses order 1042 from ORDER_TEXT into
order. The label holds only the order number and the tags here:
tags = set(order["tags"])
label = {
"order": order["id"],
"tags": sorted(tags),
}
print(json.dumps(label, indent=2))