sift icon indicating copy to clipboard operation
sift copied to clipboard

Add Dictionary difference functions

Open Hexcede opened this issue 6 months ago • 1 comments

I have written some computationally & memory efficient implementations for these already which produce the exact behaviours I demonstrated in the example code already, so I'd be happy to write up a PR if that's desirable.

  • Sift.Dictionary.difference(dictA, dictB) - Would produce a new dictionary containing values which are different in B than in A. This only considers top-level equality. This is also the inverse of Sift.Dictionary.merge.
  • Sift.Dictionary.differenceDeep(dictA, dictB) - Would produce a new dictionary containing values which are different in B than in A. Sub-dictionaries would only contain differences as well. This is also the inverse of Sift.Dictionary.mergeDeep.
local kinds = {
	Apple = true;
	Pear = true;
	
	Others = {
		Carrot = true;
		Potato = true;
	};
}

local dictA = {
	Apple = 9;
	Pear = 7;

	Others = {
		Carrot = 11;
		Potato = 15;
	};

	Kinds = kinds;
}

local dictB = {
	Apple = 10;
	Pear = 7;

	Others = {
		Carrot = 12;
	};

	Kinds = kinds;
}

-- Shallow difference, only top level equality
Sift.Dictionary.difference(dictA, dictB) -- { Apple = 10, Others = { Carrot = 12 } }

-- Deep difference, sub-dictionaries will also be deeply diffed
Sift.Dictionary.differenceDeep(dictA, dictB) -- { Apple = 10, Others = { Carrot = 12, Potato = Sift.None }, Kinds = { } }

-- Another valid implementation might omit Kinds since it has no changes. This behaviour might not be expected in some cases though, so it might be worth considering which of the two implementations makes the most sense.
-- It might also be good to consider how table equality should be treated. In the example I assume just == behaviour, but `Dictionary.equals` or `Dictionary.equalsDeep` could also be used for diffing sub-dicts.

Hexcede avatar Jan 15 '24 17:01 Hexcede