@absoluteui/helpers/set
Union, intersection, difference, and relations for arrays and Sets, with key selectors.
import { ... } from '@absoluteui/helpers/set';How to use
Section titled “How to use”Set algebra over arrays, Sets, and any iterable: union, intersection, difference, and subset checks, each with a ...By variant that compares records by a key. Array inputs return arrays in first-seen order; a Set as first argument returns a Set. The Helpers and services guide covers the shared conventions.
How do I check whether a user has the permissions a screen needs?
Section titled “How do I check whether a user has the permissions a screen needs?”isSubset answers yes or no; except lists what is missing, for a precise “you need …” message.
import { except, isSubset } from '@absoluteui/helpers/set';
const granted = new Set(['employee.read', 'leave.read', 'leave.approve']);const payrollScreen = ['employee.read', 'payroll.read', 'payroll.run'];isSubset(payrollScreen, granted); // => falseexcept(payrollScreen, granted); // => ['payroll.read', 'payroll.run']isSubset(['leave.read', 'leave.approve'], granted); // => trueHow do I find who joined and who left between two roster snapshots?
Section titled “How do I find who joined and who left between two roster snapshots?”The ...By variants compare records by a key, so objects from two API calls match by id even though they are different instances.
import { exceptBy, intersectBy } from '@absoluteui/helpers/set';
const lastMonth = [{ id: 'E-1', name: 'Asha' }, { id: 'E-2', name: 'Ben' }, { id: 'E-3', name: 'Chen' }];const thisMonth = [{ id: 'E-2', name: 'Ben' }, { id: 'E-3', name: 'Chen' }, { id: 'E-4', name: 'Dana' }];const byId = (e: { id: string }) => e.id;exceptBy(thisMonth, lastMonth, byId).map((e) => e.name); // => ['Dana'] // joinersexceptBy(lastMonth, thisMonth, byId).map((e) => e.name); // => ['Asha'] // leaversintersectBy(lastMonth, thisMonth, byId).length; // => 2How do I merge selections from several filters?
Section titled “How do I merge selections from several filters?”union keeps first-seen order and drops duplicates; symmetricDifference shows what differs between two selections, for example when comparing two saved views.
import { symmetricDifference, union } from '@absoluteui/helpers/set';
const fromDeptFilter = ['E-1', 'E-2', 'E-5'];const fromSkillFilter = ['E-2', 'E-7'];union(fromDeptFilter, fromSkillFilter); // => ['E-1', 'E-2', 'E-5', 'E-7']symmetricDifference(fromDeptFilter, fromSkillFilter); // => ['E-1', 'E-5', 'E-7']How do I list every combination of options?
Section titled “How do I list every combination of options?”cartesianProduct builds combinations, for example every site, shift, and role slot for a staffing plan. It is capped at MAX_CARTESIAN_SIZE results.
import { cartesianProduct } from '@absoluteui/helpers/set';
const slots = cartesianProduct([['Pune', 'Oslo'], ['day', 'night'], ['lead']]);slots.length; // => 4slots[1]; // => ['Pune', 'night', 'lead']cartesianProduct([Array.from({ length: 1000 }, (_, i) => i), Array.from({ length: 1001 }, (_, i) => i)]); // => throws HLP_SET_PRODUCT_TOO_LARGEAPI reference
Section titled “API reference”Functions
Section titled “Functions”cartesianProduct
All tuples picking one item from each list, first list varying slowest.
Throws HLP_SET_PRODUCT_TOO_LARGE above maxSize.
function cartesianProduct<const T extends readonly unknown[]>(lists: { readonly [K in keyof T]: Iterable<T[K]>;}, options?: CartesianProductOptions): { -readonly [K in keyof T]: T[K];}[];Example:
cartesianProduct([[1, 2], ['a', 'b']]); // => [[1, 'a'], [1, 'b'], [2, 'a'], [2, 'b']]countOccurrences
Occurrence count per item (SameValueZero), in first-occurrence order.
function countOccurrences<T>(items: Collection<T>): Map<T, number>;Example:
countOccurrences(['a', 'b', 'a']); // => new Map([['a', 2], ['b', 1]])except
Items of a not in b (set difference).
function except<T>(a: ReadonlySet<T>, b: Collection<T>): Set<T>;function except<T>(a: Collection<T>, b: Collection<T>): T[];Example:
except([1, 2, 3], [2]); // => [1, 3]exceptBy
Items of a whose key does not occur in b, deduplicated by key.
function exceptBy<T>(a: ReadonlySet<T>, b: Collection<T>, key: Key<T>): Set<T>;function exceptBy<T>(a: Collection<T>, b: Collection<T>, key: Key<T>): T[];Example:
exceptBy([{ id: 1 }, { id: 2 }], [{ id: 2 }], (x) => x.id); // => [{ id: 1 }]intersect
Items of a also in b, in a’s order.
function intersect<T>(a: ReadonlySet<T>, b: Collection<T>): Set<T>;function intersect<T>(a: Collection<T>, b: Collection<T>): T[];Example:
intersect([3, 1, 2], [2, 3]); // => [3, 2]intersectBy
Items of a whose key occurs in b, deduplicated by key.
function intersectBy<T>(a: ReadonlySet<T>, b: Collection<T>, key: Key<T>): Set<T>;function intersectBy<T>(a: Collection<T>, b: Collection<T>, key: Key<T>): T[];Example:
intersectBy([{ id: 1 }, { id: 2 }], [{ id: 2 }], (x) => x.id); // => [{ id: 2 }]isDisjoint
True when the collections share no item.
function isDisjoint<T>(a: Collection<T>, b: Collection<T>): boolean;Example:
isDisjoint([1, 2], [3]); // => trueisDisjointBy
True when the collections share no key.
function isDisjointBy<T>(a: Collection<T>, b: Collection<T>, key: Key<T>): boolean;Example:
isDisjointBy([{ id: 1 }], [{ id: 2 }], (x) => x.id); // => trueisSubset
True when every item of a is in b.
function isSubset<T>(a: Collection<T>, b: Collection<T>): boolean;Example:
isSubset([1, 2], [1, 2, 3]); // => trueisSubsetBy
True when every key of a occurs in b.
function isSubsetBy<T>(a: Collection<T>, b: Collection<T>, key: Key<T>): boolean;Example:
isSubsetBy([{ id: 1 }], [{ id: 1 }, { id: 2 }], (x) => x.id); // => trueisSuperset
True when every item of b is in a.
function isSuperset<T>(a: Collection<T>, b: Collection<T>): boolean;Example:
isSuperset([1, 2, 3], [2]); // => trueisSupersetBy
True when every key of b occurs in a.
function isSupersetBy<T>(a: Collection<T>, b: Collection<T>, key: Key<T>): boolean;Example:
isSupersetBy([{ id: 1 }, { id: 2 }], [{ id: 2 }], (x) => x.id); // => truemultisetExcept
Multiset difference: each item appears max(0, count in a - count in b) times.
function multisetExcept<T>(a: Collection<T>, b: Collection<T>): T[];Example:
multisetExcept([1, 1, 2], [1]); // => [1, 2]multisetIntersect
Multiset intersection: each item appears min(count in a, count in b) times.
function multisetIntersect<T>(a: Collection<T>, b: Collection<T>): T[];Example:
multisetIntersect([1, 1, 2], [1, 3]); // => [1]multisetUnion
Multiset union: each item appears max(count in a, count in b) times, grouped in first-occurrence order.
function multisetUnion<T>(a: Collection<T>, b: Collection<T>): T[];Example:
multisetUnion([1, 1, 2], [1, 2, 2]); // => [1, 1, 2, 2]powerSet
Every subset of the distinct items, ordered by binary counting ([] first).
Throws HLP_SET_POWERSET_TOO_LARGE when the input has more than maxItems distinct items.
function powerSet<T>(items: Collection<T>, options?: PowerSetOptions): T[][];Example:
powerSet(['a', 'b']); // => [[], ['a'], ['b'], ['a', 'b']]setEquals
True when both contain the same distinct items (order and duplicates ignored).
function setEquals<T>(a: Collection<T>, b: Collection<T>): boolean;Example:
setEquals([1, 2, 2], new Set([2, 1])); // => truesetEqualsBy
True when both contain the same distinct keys.
function setEqualsBy<T>(a: Collection<T>, b: Collection<T>, key: Key<T>): boolean;Example:
setEqualsBy([{ id: 1 }], [{ id: 1 }, { id: 1 }], (x) => x.id); // => truesymmetricDifference
Items in exactly one collection: a’s first, then b’s.
function symmetricDifference<T>(a: ReadonlySet<T>, b: Collection<T>): Set<T>;function symmetricDifference<T>(a: Collection<T>, b: Collection<T>): T[];Example:
symmetricDifference([1, 2], [2, 3]); // => [1, 3]symmetricDifferenceBy
Symmetric difference by key.
function symmetricDifferenceBy<T>(a: ReadonlySet<T>, b: Collection<T>, key: Key<T>): Set<T>;function symmetricDifferenceBy<T>(a: Collection<T>, b: Collection<T>, key: Key<T>): T[];Example:
symmetricDifferenceBy([{ id: 1 }, { id: 2 }], [{ id: 2 }, { id: 3 }], (x) => x.id); // => [{ id: 1 }, { id: 3 }]union
Items in either collection, a first.
function union<T>(a: ReadonlySet<T>, b: Collection<T>): Set<T>;function union<T>(a: Collection<T>, b: Collection<T>): T[];Example:
union([1, 2], [2, 3]); // => [1, 2, 3]union(new Set([1]), [2]); // => new Set([1, 2])unionBy
Union by key; the first item per key wins.
function unionBy<T>(a: ReadonlySet<T>, b: Collection<T>, key: Key<T>): Set<T>;function unionBy<T>(a: Collection<T>, b: Collection<T>, key: Key<T>): T[];Example:
unionBy([{ id: 1, v: 'a' }], [{ id: 1, v: 'b' }, { id: 2 }], (x) => x.id); // => [{ id: 1, v: 'a' }, { id: 2 }]Constants
Section titled “Constants”MAX_CARTESIAN_SIZE
Default maximum number of tuples from cartesianProduct.
const MAX_CARTESIAN_SIZE = 1000000;MAX_POWER_SET_ITEMS
Default maximum distinct input size for powerSet (2^20 subsets).
const MAX_POWER_SET_ITEMS = 20;Interfaces
Section titled “Interfaces”CartesianProductOptions
interface CartesianProductOptions { readonly maxSize?: number;}PowerSetOptions
interface PowerSetOptions { readonly maxItems?: number;}