Skip to content

Instantly share code, notes, and snippets.

@alexburner
Last active February 1, 2018 06:50
Show Gist options
  • Save alexburner/5924703f90e7e5d595c528cf7eaa4c6f to your computer and use it in GitHub Desktop.
Save alexburner/5924703f90e7e5d595c528cf7eaa4c6f to your computer and use it in GitHub Desktop.
Object list XOR
// Find the difference between two lists of objects
const xor = <T>(
listA: T[],
listB: T[],
keys: (keyof T)[] // which obj keys to use for uniqueness check
): T[] => {
// el -> string (for map key)
const stringify = el => keys.reduce((str, key) => str + el[key], '')
// List A el -> map
const map = listA.reduce((map, el) => {
const elKey = stringify(el)
map.set(elKey, el)
return map
}, new Map() as Map<string, T>)
// List B el <- map if has match
// List B el -> map if unique
listB.forEach(el => {
const elKey = stringify(el)
if (map.has(elKey)) map.delete(elKey)
else map.set(elKey, el)
})
// Now map holds XOR of A & B
return Array.from(map.values())
}
// TEST
interface Filter {
subject: string
operator: string
operand: number
}
const a: Filter[] = [
{ subject: 'key', operator: '=', operand: 4 },
{ subject: 'key', operator: '=', operand: 5 },
{ subject: 'key', operator: '=', operand: 6 },
]
const b: Filter[] = [
{ subject: 'key', operator: '=', operand: 5 },
{ subject: 'key', operator: '=', operand: 6 },
{ subject: 'key', operator: '=', operand: 7 },
]
const x = xor<Filter>(a, b, ['subject', 'operator', 'operand'])
console.log(x)
/*
[ { subject: 'key', operator: '=', operand: 4 },
{ subject: 'key', operator: '=', operand: 7 } ]
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment