Closed hitengajjar closed 4 years ago
That is a great idea. I would want to avoid adding another method, especially with that common of a word, however I think it might be good to just have a -
minus ability, like it currently has the addition ability.
rough mockup would look like:
def __sub__(self, other):
output = self.__class__(**self.__box_config())
for item in self:
if item not in other:
output[item] = self[item]
elif isinstance(self.get(item), dict) and isinstance(other.get(item), dict):
output[item] = self[item] - other[item]
return output
Returning something like:
from box import Box
box_1 = Box(a={'1': 1, '2': '2'}, b='b', c='c')
box_2 = Box(a={'1': 'different_value'}, b='b')
box_1 - box_2
# Out[2]: <Box: {'a': {'2': '2'}, 'c': 'c'}>
This would all be key based. To do a compare that checked actual value differences will have to think of some way to be able to present that information back. Possibly putting conflicting values into a namedtuple or something.
Hey Chris, Thanks for considering this as a feature. Though your suggestion looks reasonable, still it doesn't exactly provide a report on what's the exact difference between 2 or more boxes (and think this is unique feature that doesn't exist in other dict
based libraries I know).
Just to be sure you mean -
operator will act as it works on set()
. Is that correct?
If yes, then I don't think value difference should be presented in tuple form. Maybe, in such case output key-value pair from the first box in operation.
Just found a dictionary comparison solution exists called dictdiffer (readthedocs for it) in case you were looking for a fast solution.
Quick test run with box seems fine:
In [5]: from dictdiffer import diff
In [6]: a = Box(test_dict)
In [7]: b = Box(test_dict, another_key=2)
In [8]: diff(a, b)
Out[8]: <generator object diff.<locals>._diff_recursive at 0x077735F0>
In [10]: list(diff(a,b))
Out[10]: [('add', '', [('another_key', 2)])]
In [11]: b
Out[11]: <Box: {'key1': 'value1', 'not$allowed': 'fine_value', 'BigCamel': 'hi', 'alist': [{'a': 1}], 'Key 2': {'Key 3': 'Value 3', 'Key4': {'Key5': 'Value5'}}, 'another_key': 2}>
In [12]: b.key1 = 5
In [13]: list(diff(a,b))
Out[13]: [('change', 'key1', ('value1', 5)), ('add', '', [('another_key', 2)])]
I tried and failed to look to have a compare functionality that can provide a report of what's different between 2 boxes. I notice I can compare 2 Boxes with a comparison operator e.g.
Box(a=1, b=dict(c=1)) == Box(a=1, b=dict(c=1))
however it would be nice to have a specialBox.compare(box2,...)
method that also generates a report (maybe a Box object itself)