I have a sorted (Mongodb) collection of objects:
{"_id": ObjectId(...), "person": "Homer", "order": 1},
{"_id": ObjectId(...), "person": "Marge", "order": 2}
I would like to prepend, append or insert between two objects another object. I’ve tried this using float numbers like this:
{"_id": ObjectId(...), "person": "Homer", "order": 1},
{"_id": ObjectId(...), "person": "Bart", "order": 1.5},
{"_id": ObjectId(...), "person": "Marge", "order": 2}
Order value is the arithmetic mean of fields order in the previous and the next object. It works works as long as numbers don’t look like 1.9999999. Then it is rounded to 2 and the collection isn’t sorted.
I could use integers in this way:
{"_id": ObjectId(...), "person": "Homer", "order": 1},
{"_id": ObjectId(...), "person": "Bart", "order": 2},
{"_id": ObjectId(...), "person": "Marge", "order": 3}
but it means the need to modify the other objects and I would rather avoid that.
I thought about using Strings and lexical sorting to prevent order:
{"_id": ObjectId(...), "person": "Homer", "order": aa},
{"_id": ObjectId(...), "person": "Bart", "order": ab},
{"_id": ObjectId(...), "person": "Marge", "order": bb}
but it seems difficult to implement. Is there any easier way to do it?
I think that the floats approach makes the most sense.
Assuming that you start off with all locations as integers, it would take a lot of swaps until you run into precision problems.
I suggest that whenever you change the “order” of an item, see if it’s too close to one of its neighbors. If it is, reassign the values of all of the objects (so they are all integers again).
If you set a limit of |x-y| >= 2**(-50), which is fine since python keeps 53 precision bits for floats, it will take at least 50 unlucky swaps before you need to reassign the orders.
Edit: I just saw that you didn’t ask about Python specifically. Replace the precision with whatever makes sense for your system.