Skip to content

Instantly share code, notes, and snippets.

@sebinsua
Last active May 15, 2021 21:14
Show Gist options
  • Save sebinsua/f0ccc00b1e2fa510c827d91d59425baf to your computer and use it in GitHub Desktop.
Save sebinsua/f0ccc00b1e2fa510c827d91d59425baf to your computer and use it in GitHub Desktop.
#!/usr/bin/env node
function intersect(x, y) {
const setX = new Set(x);
const setY = new Set(y);
let intersected = [];
for (let value of setX) {
// I worked with Sets because of an assumption that this is
// cheaper than Array#includes.
if (setY.has(value)) {
intersected.push(value);
}
}
return intersected;
}
function union(x, y) {
return Array.from(new Set([...x, ...y]));
}
function difference(x, y) {
const setX = new Set(x);
const setY = new Set(y);
let complements = [];
for (let value of setY) {
if (!setX.has(value)) {
complements.push(value);
}
}
return complements;
}
// Apparently also known as a disjunctive union.
function symmetricDifference(a, b) {
const c = union(a, b);
// Probably there's a more efficent way of doing this
// but this is at least expressive.
return difference(intersect(a, b), c);
}
console.log(intersect([1, 2, 3, 4, 11], [3, 4, 5, 6, 7, 8, 9]));
console.log(union([1, 2, 3, 4, 11], [3, 4, 5, 6, 7, 8, 9]));
console.log(difference([1, 2, 3, 4, 11], [3, 4, 5, 6, 7, 8, 9]));
console.log(symmetricDifference([1, 2, 3, 102], [2, 3, 4, 5, 99, 100]));
@sebinsua
Copy link
Author

sebinsua commented May 14, 2021

function createDifference(identity) {
  return function difference(xs, ys) {
    const xsMap = new Map(xs.map(x => [identity ? identity(x) : x, x]));
	const ysMap = new Map(ys.map(y => [identity ? identity(y) : y, y]));
	  
	let complements = [];
	for (let [key, value] of xsMap) {
	  if (!ysMap.has(key)) {
	    complements.push(value);
	  }
	}
  
    return complements;
  };
}

But what about when we want to get out all items with the same identity but a changed inner property?

function createChanged(identity) {
  return function changed(xs, ys) {
    const xsMap = new Map(xs.map(x => [identity ? identity(x) : x, x]));
	const ysMap = new Map(ys.map(y => [identity ? identity(y) : y, y]));
	  
	let items = [];
	for (let [key, value] of xsMap) {
	  if (ysMap.has(key) && isEqual(ysMap.get(key), value) === false) {
	    items.push(ysMap.get(key));
	  }
	}
  
    return items;
  };
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment