Skip to content

Instantly share code, notes, and snippets.

@jda0
Created February 25, 2021 21:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jda0/a5508cf6f017479e88cff1e2ca626026 to your computer and use it in GitHub Desktop.
Save jda0/a5508cf6f017479e88cff1e2ca626026 to your computer and use it in GitHub Desktop.
Set operations for objects (as opposed to iterables)
/**
* 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),
]);
};
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