or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

bins.mdindex.mditerables.mdsearch.mdsequences.mdsets.mdstatistics.mdtransformations.md
tile.json

sets.mddocs/

Sets

Set theory operations for computing unions, intersections, differences, and relationships between iterables. These functions implement mathematical set operations and work with any iterable type.

Capabilities

Set Operations

These functions create new InternSet instances containing the results of set operations. InternSet extends the native Set class to handle non-primitive keys by using value-based equality instead of reference equality.

union

Returns a new InternSet containing every distinct value that appears in any of the given iterables.

/**
 * Returns a new InternSet containing every distinct value from all iterables
 * @param iterables - One or more iterables to unite
 * @returns InternSet with all unique values from input iterables
 */
function union(...iterables: Iterable<any>[]): InternSet<any>;

Usage Examples:

import { union } from "d3-array";

union([0, 2, 1, 0], [1, 3]); // InternSet {0, 2, 1, 3}
union([1, 2], [2, 3], [3, 4]); // InternSet {1, 2, 3, 4}

// Works with any iterable
union(new Set([1, 2]), new Set([2, 3])); // InternSet {1, 2, 3}
union("hello", "world"); // InternSet {'h', 'e', 'l', 'o', 'w', 'r', 'd'}

intersection

Returns a new InternSet containing every distinct value that appears in all of the given iterables.

/**
 * Returns a new InternSet containing values that appear in all iterables
 * @param iterables - One or more iterables to intersect
 * @returns InternSet with values common to all input iterables
 */
function intersection(...iterables: Iterable<any>[]): InternSet<any>;

Usage Examples:

import { intersection } from "d3-array";

intersection([0, 2, 1, 0], [1, 3]); // InternSet {1}
intersection([1, 2, 3], [2, 3, 4], [2, 4, 5]); // InternSet {2}

// Empty intersection
intersection([1, 2], [3, 4]); // InternSet {} (empty)

// Works with any iterable
intersection(new Set([1, 2, 3]), [2, 3, 4]); // InternSet {2, 3}

difference

Returns a new InternSet containing every value in the first iterable that is not in any of the other iterables.

/**
 * Returns a new InternSet with values from first iterable not in others
 * @param iterable - The source iterable
 * @param others - One or more iterables to subtract from the source
 * @returns InternSet with values in source but not in others
 */
function difference(iterable: Iterable<any>, ...others: Iterable<any>[]): InternSet<any>;

Usage Examples:

import { difference } from "d3-array";

difference([0, 1, 2, 0], [1]); // InternSet {0, 2}
difference([1, 2, 3, 4], [2, 3], [4, 5]); // InternSet {1}

// Complete difference
difference([1, 2], [1, 2, 3]); // InternSet {} (empty)

// Works with any iterable
difference(new Set([1, 2, 3, 4]), [2, 4]); // InternSet {1, 3}

Set Relationships

These functions test relationships between sets, returning boolean values.

superset

Returns true if the first iterable is a superset of the second (contains all values from the second).

/**
 * Returns true if a is a superset of b (every value in b is also in a)
 * @param a - The potential superset iterable
 * @param b - The potential subset iterable
 * @returns True if a contains all values from b
 */
function superset(a: Iterable<any>, b: Iterable<any>): boolean;

Usage Examples:

import { superset } from "d3-array";

superset([0, 2, 1, 3, 0], [1, 3]); // true
superset([1, 2, 3], [1, 2, 3, 4]); // false (missing 4)
superset([1, 2, 3], [1, 2]); // true

// Works with any iterable
superset(new Set([1, 2, 3, 4]), [2, 4]); // true
superset("hello", "el"); // true ('e' and 'l' are in "hello")

subset

Returns true if the first iterable is a subset of the second (all values in first exist in second).

/**
 * Returns true if a is a subset of b (every value in a is also in b)
 * @param a - The potential subset iterable
 * @param b - The potential superset iterable
 * @returns True if b contains all values from a
 */
function subset(a: Iterable<any>, b: Iterable<any>): boolean;

Usage Examples:

import { subset } from "d3-array";

subset([1, 3], [0, 2, 1, 3, 0]); // true
subset([1, 2, 3, 4], [1, 2, 3]); // false (4 not in second set)
subset([1, 2], [1, 2, 3]); // true

// Empty set is subset of any set
subset([], [1, 2, 3]); // true

// Works with any iterable
subset([2, 4], new Set([1, 2, 3, 4])); // true

disjoint

Returns true if the two iterables are disjoint (contain no shared values).

/**
 * Returns true if a and b are disjoint (contain no shared values)
 * @param a - The first iterable
 * @param b - The second iterable
 * @returns True if no values appear in both iterables
 */
function disjoint(a: Iterable<any>, b: Iterable<any>): boolean;

Usage Examples:

import { disjoint } from "d3-array";

disjoint([1, 3], [2, 4]); // true (no common values)
disjoint([1, 2, 3], [3, 4, 5]); // false (3 is common)
disjoint([1, 2], [3, 4]); // true

// Empty sets are disjoint with everything
disjoint([], [1, 2, 3]); // true
disjoint([], []); // true

// Works with any iterable
disjoint(new Set([1, 2]), [3, 4]); // true
disjoint("abc", "def"); // true (no common characters)
disjoint("abc", "bcd"); // false ('b' and 'c' are common)

InternSet

The InternSet class extends JavaScript's native Set to provide value-based equality for non-primitive keys.

/**
 * Creates a new InternSet with value-based key equality
 * @param iterable - Optional iterable to initialize the set
 * @param key - Optional key function for value comparison
 */
class InternSet<T> extends Set<T> {
  constructor(iterable?: Iterable<T>, key?: (value: T) => any);
}

Usage Examples:

import { InternSet } from "d3-array";

// Regular Set uses reference equality for objects
const regularSet = new Set();
regularSet.add({name: "Alice"});
regularSet.add({name: "Alice"}); // Different reference, so both are added
console.log(regularSet.size); // 2

// InternSet uses value equality
const internSet = new InternSet();
internSet.add({name: "Alice"});
internSet.add({name: "Alice"}); // Same value, so only one is kept
console.log(internSet.size); // 1

// Using custom key function
const personSet = new InternSet([], person => person.id);
personSet.add({id: 1, name: "Alice"});
personSet.add({id: 1, name: "Alice Smith"}); // Same id, so replaces first
console.log(personSet.size); // 1

InternMap

The InternMap class extends JavaScript's native Map to provide value-based equality for non-primitive keys. It is used by grouping functions like group, rollup, and index to allow objects, dates, and other complex types as keys.

/**
 * Creates a new InternMap with value-based key equality
 * @param iterable - Optional iterable of [key, value] pairs to initialize the map
 * @param key - Optional key function for value comparison
 */
class InternMap<K, V> extends Map<K, V> {
  constructor(iterable?: Iterable<[K, V]>, key?: (value: K) => any);
}

Usage Examples:

import { InternMap } from "d3-array";

// Regular Map uses reference equality for objects
const regularMap = new Map();
const key1 = {type: "user"};
const key2 = {type: "user"}; 
regularMap.set(key1, "Alice");
regularMap.set(key2, "Bob"); // Different reference, creates new entry
console.log(regularMap.size); // 2

// InternMap uses value equality
const internMap = new InternMap();
internMap.set({type: "user"}, "Alice");
internMap.set({type: "user"}, "Bob"); // Same value, overwrites first
console.log(internMap.size); // 1
console.log(internMap.get({type: "user"})); // "Bob"

// Using custom key function
const dateMap = new InternMap([], date => date.getTime());
dateMap.set(new Date("2023-01-01"), "New Year");
dateMap.set(new Date("2023-01-01"), "January 1st"); // Same timestamp, overwrites
console.log(dateMap.size); // 1
console.log(dateMap.get(new Date("2023-01-01"))); // "January 1st"

// Common with grouping operations
import { group } from "d3-array";

const data = [
  {date: new Date("2023-01-01"), value: 10},
  {date: new Date("2023-01-01"), value: 20},
  {date: new Date("2023-01-02"), value: 30}
];

// group() returns an InternMap
const grouped = group(data, d => d.date);
console.log(grouped.get(new Date("2023-01-01"))); // Array with both entries

Practical Examples

Data Deduplication

import { union, InternSet } from "d3-array";

const users1 = [
  {id: 1, name: "Alice"},
  {id: 2, name: "Bob"}
];

const users2 = [
  {id: 2, name: "Bob"},
  {id: 3, name: "Charlie"}
];

// Combine and deduplicate by id
const allUsers = new InternSet([], user => user.id);
union(users1, users2).forEach(user => allUsers.add(user));
// Results in users with ids 1, 2, 3 (no duplicates)

Filtering by Set Membership

import { intersection, difference } from "d3-array";

const validIds = [1, 2, 3, 4, 5];
const requestedIds = [2, 4, 6, 8];
const existingIds = [1, 3, 5, 7];

// Find valid requested IDs
const validRequested = intersection(validIds, requestedIds); // {2, 4}

// Find IDs to create (valid + requested - existing)
const toCreate = difference(intersection(validIds, requestedIds), existingIds); // {2, 4}

Access Control

import { subset, superset, intersection } from "d3-array";

const userPermissions = ["read", "write"];
const requiredPermissions = ["read"];
const adminPermissions = ["read", "write", "delete", "admin"];

// Check if user has required permissions
const hasAccess = superset(userPermissions, requiredPermissions); // true

// Check if user is subset of admin
const isSubsetOfAdmin = subset(userPermissions, adminPermissions); // true

// Find common permissions
const commonPerms = intersection(userPermissions, adminPermissions); // {"read", "write"}

Data Comparison

import { disjoint, intersection, difference, union } from "d3-array";

const lastWeekUsers = ["alice", "bob", "charlie"];
const thisWeekUsers = ["bob", "charlie", "diana"];

// Are user sets completely different?
const completelyDifferent = disjoint(lastWeekUsers, thisWeekUsers); // false

// Returning users
const returningUsers = intersection(lastWeekUsers, thisWeekUsers); // {"bob", "charlie"}

// New users this week
const newUsers = difference(thisWeekUsers, lastWeekUsers); // {"diana"}

// Users who left
const leftUsers = difference(lastWeekUsers, thisWeekUsers); // {"alice"}

// All users ever
const allUsers = union(lastWeekUsers, thisWeekUsers); // {"alice", "bob", "charlie", "diana"}