Skip to main content

differenceWith()

differenceWith<T, U>(array, values, comparator): T[]

Creates an array of values from the first array that are not included in the second array, using a comparator function to determine equality.


Type Parametersโ€‹

T: Tโ€‹

The type of elements in the source array.

U: U = Tโ€‹

The type of elements in the values array (defaults to T).


Parametersโ€‹

array: readonly T[]โ€‹

The source array to inspect.

values: readonly U[]โ€‹

The array of values to exclude.

comparator: (a, b) => booleanโ€‹

The function invoked to compare elements.


Returns: T[]โ€‹

A new array of filtered values.


Sinceโ€‹

2.0.0


Performanceโ€‹

O(n ร— m) โ€” custom comparators cannot leverage Set optimization.


Also known asโ€‹

differenceWith (Lodash, es-toolkit, Remeda, Ramda, Effect) ยท โŒ (Radashi, Modern Dash, Antfu)


Exampleโ€‹

// Same types
const objects = [{ x: 1, y: 2 }, { x: 2, y: 1 }];
differenceWith(objects, [{ x: 1, y: 2 }], (a, b) => a.x === b.x && a.y === b.y);
// => [{ x: 2, y: 1 }]

// Different types
differenceWith(
[{ id: 1 }, { id: 2 }, { id: 3 }],
[2, 4],
(obj, id) => obj.id === id
);
// => [{ id: 1 }, { id: 3 }]

// Tolerance comparison
differenceWith([1.1, 2.2, 3.3], [1.0, 3.0], (a, b) => Math.abs(a - b) < 0.5);
// => [2.2]

How it works?โ€‹

Compares elements using a custom comparator function.


Use Casesโ€‹

Filter objects with custom deep equality ๐Ÿ“Œโ€‹

Compare complex objects using a custom comparator for deep or partial matching. Perfect for comparing objects that don't share the same reference but have equivalent values.

const inventory = [
{ name: "Apple", quantity: 10 },
{ name: "Banana", quantity: 5 },
{ name: "Orange", quantity: 8 },
];
const soldOut = [{ name: "Banana", quantity: 5 }];

const inStock = differenceWith(
inventory,
soldOut,
(a, b) => a.name === b.name && a.quantity === b.quantity
);
// => [{ name: "Apple", quantity: 10 }, { name: "Orange", quantity: 8 }]

Exclude items with tolerance-based comparisonโ€‹

Filter out elements where values are "close enough" rather than exactly equal. Perfect for numeric comparisons with floating-point precision or threshold-based filtering.

const measurements = [10.01, 20.02, 30.03, 40.04];
const calibrationErrors = [10.0, 30.0];

const validMeasurements = differenceWith(
measurements,
calibrationErrors,
(a, b) => Math.abs(a - b) < 0.1
);
// => [20.02, 40.04]

Filter with cross-type comparisonโ€‹

Compare arrays of different types using a custom mapping logic. Perfect for matching entities from different sources (e.g., IDs vs full objects, strings vs objects).

const users = [
{ id: 1, name: "Alice" },
{ id: 2, name: "Bob" },
{ id: 3, name: "Charlie" },
];
const bannedUserIds = [2, 3];

const activeUsers = differenceWith(
users,
bannedUserIds,
(user, id) => user.id === id
);
// => [{ id: 1, name: "Alice" }]