Object diff

JavaScript

console.clear();
let a = {
	a: 1,
	b: 2,
	o: [ 1, 2 ],
	c: {
		x: 1,
		y: 2
	},
	d: {
		w: 1
	}
};

let b = {
	a: 1,
	b: 200,
	o: [ 3, 2 ],
	c: {
		x: 1,
		y: 3
	},
	d: {
		w: 1
	}
};

let c = {
	a: 1,
	b: 200,
	o: [ 3, 2 ],
	c: {
		x: 1,
		y: 3
	},
	d: {
		w: 1
	}
};

const isPrimitive = val => ["string", "number"].includes(typeof val);
const addDiffMetadata = (...objs) =>
	[...new Set([].concat(...objs.map(obj => 
		Object.keys(obj)
			.filter(key => {
				let value = obj[key];
				
				if (isPrimitive(value)) {
					obj[key] = () => { };
					obj[key].valueOf = () => value;
					obj[key].isDifferent = !objs.every(o => o[key] == value);
					
					return false;
				}
				
				return true;
			})
		)))]
		.map(key => objs.map(o => o[key]))
		.forEach(r => addDiffMetadata(...r));

addDiffMetadata(a, b, c);

var g = {
	a: 1
};

console.log();
console.log(a.a + "1");
console.log(a);

/* // Print results like normal
console.group("a");
for (let prop in a)
  console.log(prop, a[prop], a[prop].isDifferent);

console.groupEnd();
console.group("b");

for (let prop in b)
  console.log(prop, a[prop], a[prop].isDifferent);

console.groupEnd();

// Tests
console.group("%cRunning tests...", "color:#34f");
console.assert(a.a.isDifferent === false, "regular unchanged");
console.assert(a.b.isDifferent === true, "regular changed");
console.assert(a.c.x.isDifferent === false, "nested unchanged");
console.assert(a.c.y.isDifferent === true, "nested changed");
console.assert(a.o[0].isDifferent === true, "array unchanged");
console.assert(a.o[1].isDifferent === false, "array unchanged");
console.log("%cTests completed, any errors are above.", "color:#34f");
console.groupEnd(); */