Created
February 25, 2021 21:30
-
-
Save jda0/a5508cf6f017479e88cff1e2ca626026 to your computer and use it in GitHub Desktop.
Set operations for objects (as opposed to iterables)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Returns the difference of the first and other objects provided. | |
* @param {any} x | |
* @param {any} ys | |
*/ | |
export const difference = (x, ...ys) => | |
Object.fromEntries( | |
Object.entries(x).filter(([k, v]) => !ys.some(y => y[k] === v)), | |
); | |
/** | |
* Returns the symmetric difference of the two objects provided, | |
* using values from `a` if the same key appears in both objects with | |
* different values. | |
* @param {any} a | |
* @param {any} b | |
*/ | |
export const symmetricDifference = (a, b) => { | |
const _a = Object.assign({}, a); | |
return Object.fromEntries([ | |
...Object.entries(b || {}).filter( | |
([k, v]) => !(_a[k] === v && delete _a[k]), | |
), | |
...Object.entries(_a).filter(([k, v]) => b[k] !== v), | |
]); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { difference, symmetricDifference } from './object'; | |
describe('utils | object | difference', () => { | |
it('finds the difference of two objects', () => { | |
const a = { a: 5, b: 8, c: 13, d: 21 }; | |
const b = { b: 8, c: 4, d: 21, e: 10.5 }; | |
// from a, only 'a' and 'c' do not have the same value in b. | |
const expectation = { a: 5, c: 13 }; | |
expect(difference(a, b)).toEqual(expectation); | |
}); | |
it('finds the difference of three objects', () => { | |
const a = { a: 5, b: 8, c: 13, d: 21 }; | |
const b = { b: 8, c: 4 }; | |
const c = { c: 4, d: 21, e: 10.5 }; | |
// from a, only 'a' and 'c' do not have the same value in b. | |
const expectation = { a: 5, c: 13 }; | |
expect(difference(a, b, c)).toEqual(expectation); | |
}); | |
it('throws as expected', () => { | |
expect(() => difference({}, null)).not.toThrowError(); | |
expect(() => difference({}, undefined)).not.toThrow(); | |
expect(() => difference(null, {})).toThrow(); | |
expect(() => difference(null, null)).toThrow(); | |
expect(() => difference(null, undefined)).toThrow(); | |
}); | |
}); | |
describe('utils | object | symmetricdifference', () => { | |
it('finds the difference of two objects', () => { | |
const a = { a: 5, b: 8, c: 13, d: 21 }; | |
const b = { b: 8, c: 4, d: 21, e: 10.5 }; | |
// `a['b'] == b['b']` and `a['d'] == b['d']`, prefer a['c'] | |
const expectation = { a: 5, c: 13, e: 10.5 }; | |
expect(symmetricDifference(a, b)).toEqual(expectation); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment