본문으로 건너뛰기

differenceBy

Returns elements from the source array that are not present in the exclude array, using a transformation function to determine element equality. Creates a new array containing elements from the source array that do not have matching transformed values in the exclude array. The mapper function is applied to elements from both arrays to extract comparable values.

Signature​

const differenceBy: <Type1, Type2>(source: Type1[], exclude: Type2[], mapper: (item: Type1 | Type2) => unknown) => Type1[]

Parameters​

NameTypeDescription
source-Source array that serves as the base for comparison
exclude-Array containing elements to exclude from the result
mapper-Function to transform array elements into comparable values

Returns​

Array of elements that exist only in the source array

Examples​

Compare objects by ID​

import { differenceBy } from '@winglet/common-utils';

const users = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
{ id: 3, name: 'Charlie' }
];
const toRemove = [
{ id: 1, name: 'Alice Updated' },
{ id: 2, name: 'Bob Updated' }
];

const result = differenceBy(users, toRemove, user => user.id);
console.log(result); // [{ id: 3, name: 'Charlie' }]

Compare strings by length​

const words = ['apple', 'banana', 'apricot', 'cherry'];
const excludeWords = ['grape', 'lemon']; // length 5

const result = differenceBy(words, excludeWords, word => word.length);
console.log(result); // ['banana', 'apricot', 'cherry'] (apple excluded, length 5)

Complex object comparison​

interface User {
id: number;
name: string;
department: string;
role: string;
}

const employees: User[] = [
{ id: 1, name: 'John', department: 'IT', role: 'admin' },
{ id: 2, name: 'Jane', department: 'HR', role: 'user' },
{ id: 3, name: 'Bob', department: 'IT', role: 'admin' }
];

const toExclude: User[] = [
{ id: 1, name: 'John Smith', department: 'IT', role: 'admin' },
{ id: 2, name: 'Jane Doe', department: 'HR', role: 'user' }
];

// Compare by department-role combination
const result = differenceBy(
employees,
toExclude,
user => `${user.department}-${user.role}`
);
console.log(result); // [{ id: 3, name: 'Bob', ... }]

Nested object comparison​

const products = [
{ id: 1, details: { category: 'electronics', price: 100 } },
{ id: 2, details: { category: 'books', price: 20 } },
{ id: 3, details: { category: 'electronics', price: 200 } }
];

const excludeProducts = [
{ id: 1, details: { category: 'electronics', price: 150 } }
];

const result = differenceBy(
products,
excludeProducts,
product => product.details.category
);
console.log(result); // [{ id: 2, details: { category: 'books', ... } }]

Working with different types​

interface Person { name: string; age: number; }
interface Employee { name: string; age: number; id: number; }

const people: Person[] = [
{ name: 'Alice', age: 30 },
{ name: 'Bob', age: 25 },
{ name: 'Charlie', age: 35 }
];

const employees: Employee[] = [
{ name: 'Alice', age: 30, id: 1 },
{ name: 'Bob', age: 25, id: 2 }
];

const nonEmployees = differenceBy(people, employees, person => person.name);
console.log(nonEmployees); // [{ name: 'Charlie', age: 35 }]

Playground​

import { differenceBy } from '@winglet/common-utils';

const users = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
{ id: 3, name: 'Charlie' }
];
const toRemove = [
{ id: 1, name: 'Alice Updated' },
{ id: 2, name: 'Bob Updated' }
];

const result = differenceBy(users, toRemove, user => user.id);
console.log(result); // [{ id: 3, name: 'Charlie' }]

Notes​

Performance: Uses Set for O(1) average case lookup after mapping exclude array. Time complexity is O(n + m) where n is source length and m is exclude length.

Mapper Function: The mapper function is called once for each element in both arrays. Ensure the mapper function is pure and returns consistent values for the same input.

Type Safety: Supports different types for source and exclude arrays as long as the mapper function can handle both types and returns comparable values.

Order Preservation: Maintains the original order of elements from the source array in the result array.