Skip to main content

isEqual()

isEqual(value, other): boolean

Performs a deep comparison between two values to determine if they are equivalent.

note

Supports Date, RegExp, Map, Set, arrays, and plain objects. Uses SameValueZero (NaN === NaN). Handles circular references.


Parametersโ€‹

value: unknownโ€‹

The value to compare.

other: unknownโ€‹

The other value to compare.


Returns: booleanโ€‹

true if the values are equivalent, else false.


Sinceโ€‹

2.0.0


Performanceโ€‹

O(n) where n is the total number of properties/elements to compare. O(nยฒ) for Sets containing objects (due to deep matching).


Exampleโ€‹

// Primitives
isEqual(1, 1); // => true
isEqual('hello', 'hello'); // => true
isEqual(NaN, NaN); // => true

// Objects and arrays
isEqual({ a: 1 }, { a: 1 }); // => true
isEqual([1, 2, 3], [1, 2, 3]); // => true
isEqual({ a: { b: 2 } }, { a: { b: 2 } }); // => true

// Built-in types
isEqual(new Date('2024-01-01'), new Date('2024-01-01')); // => true
isEqual(/abc/gi, /abc/gi); // => true
isEqual(new Map([['a', 1]]), new Map([['a', 1]])); // => true
isEqual(new Set([1, 2]), new Set([1, 2])); // => true

// Different values
isEqual({ a: 1 }, { a: 2 }); // => false
isEqual([1, 2], [1, 2, 3]); // => false

// Different types
isEqual([], {}); // => false
isEqual(new Date(), {}); // => false

How it works?โ€‹

Performs deep comparison between two values to determine equivalence.

Deep Comparisonโ€‹

Supported Typesโ€‹

TypeComparison
PrimitivesObject.is (NaN === NaN)
ArraysElement-by-element
ObjectsProperty-by-property
DateTimestamp comparison
RegExpSource + flags
MapKey-value pairs
SetAll elements

NaN Handlingโ€‹

Circular Referencesโ€‹


Use Casesโ€‹

Deep Object Comparison for state changes ๐Ÿ“Œโ€‹

Compare complex objects to detect state changes. Essential for React/Vue change detection and memoization.

import { isEqual } from "pithos/arkhe/is/predicate/is-equal";

const prevState = {
user: { name: "John", settings: { theme: "dark", notifications: true } },
items: [1, 2, 3],
};

const nextState = {
user: { name: "John", settings: { theme: "dark", notifications: true } },
items: [1, 2, 3],
};

// Deep comparison - returns true even though different references
console.log(isEqual(prevState, nextState)); // true
console.log(prevState === nextState); // false (reference comparison)

// Detect actual changes
const changedState = { ...nextState, user: { ...nextState.user, name: "Jane" } };
console.log(isEqual(prevState, changedState)); // false

Test Assertions for complex data ๐Ÿ“Œโ€‹

Assert equality of complex data structures in tests. Critical for comprehensive test coverage.

import { isEqual } from "pithos/arkhe/is/predicate/is-equal";

function testUserTransformation() {
const input = { firstName: "John", lastName: "Doe", age: 30 };
const result = transformUser(input);

const expected = {
fullName: "John Doe",
age: 30,
metadata: { transformed: true, timestamp: result.metadata.timestamp },
};

if (!isEqual(result, expected)) {
throw new Error(`Expected ${JSON.stringify(expected)}, got ${JSON.stringify(result)}`);
}

console.log("Test passed!");
}

// Works with special types too
console.log(isEqual(new Date("2024-01-01"), new Date("2024-01-01"))); // true
console.log(isEqual(/abc/gi, /abc/gi)); // true
console.log(isEqual(new Set([1, 2]), new Set([1, 2]))); // true
console.log(isEqual(new Map([["a", 1]]), new Map([["a", 1]]))); // true

Cache Invalidation with key comparisonโ€‹

Determine if cached values should be invalidated. Important for efficient caching strategies.

import { isEqual } from "pithos/arkhe/is/predicate/is-equal";

class MemoizedFetcher {
private cache = new Map<string, { params: unknown; data: unknown }>();

async fetch(key: string, params: unknown): Promise<unknown> {
const cached = this.cache.get(key);

// Check if params are the same (deep comparison)
if (cached && isEqual(cached.params, params)) {
console.log(`Cache hit for ${key}`);
return cached.data;
}

console.log(`Cache miss for ${key}, fetching...`);
const data = await this.fetchFromApi(key, params);
this.cache.set(key, { params, data });
return data;
}

private async fetchFromApi(key: string, params: unknown) {
// Simulate API call
return { key, params, timestamp: Date.now() };
}
}

const fetcher = new MemoizedFetcher();
await fetcher.fetch("users", { page: 1, limit: 10 }); // Cache miss
await fetcher.fetch("users", { page: 1, limit: 10 }); // Cache hit
await fetcher.fetch("users", { page: 2, limit: 10 }); // Cache miss (different params)