Lodash intersectionWith with Custom Comparator

Lodash's _.intersectionWith method computes the intersection of multiple arrays based on a custom comparison logic rather than standard identity comparison. This article explains the syntax of _.intersectionWith, describes how to construct a custom comparator function, and provides clear, practical examples demonstrating how to match arrays containing complex objects or case-insensitive data.

Syntax and Parameters

The syntax for _.intersectionWith is as follows:

_.intersectionWith([arrays], [comparator])

Creating and Passing a Custom Comparator

A custom comparator function receives an item from the first array (arrVal) and an item from the subsequent array (othVal). When the comparator returns true, the matching element from the first array is included in the output.

Example 1: Comparing Objects by Property

When working with arrays of objects, you often need to find intersections based on a single identifier, such as an id or sku:

const _ = require('lodash');

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

const listB = [
  { id: 2, name: 'Robert' },
  { id: 4, name: 'David' }
];

// Custom comparator comparing elements by the 'id' field
const customComparator = (itemA, itemB) => itemA.id === itemB.id;

const result = _.intersectionWith(listA, listB, customComparator);

console.log(result);
// Output: [ { id: 2, name: 'Bob' } ]

Notice that the resulting array retains the element from the first array (listA).

Example 2: Deep Object Comparison with _.isEqual

If you need to verify that nested objects match completely rather than checking a single property, you can pass Lodash's _.isEqual directly as the comparator:

const _ = require('lodash');

const objectsA = [
  { user: { id: 1, role: 'admin' } },
  { user: { id: 2, role: 'editor' } }
];

const objectsB = [
  { user: { id: 1, role: 'admin' } },
  { user: { id: 3, role: 'viewer' } }
];

const matchedObjects = _.intersectionWith(objectsA, objectsB, _.isEqual);

console.log(matchedObjects);
// Output: [ { user: { id: 1, role: 'admin' } } ]

Example 3: Case-Insensitive String Comparison

Custom comparators can also handle string normalization, such as ignoring letter casing:

const _ = require('lodash');

const letters1 = ['apple', 'BANANA', 'Orange'];
const letters2 = ['Apple', 'banana', 'GRAPE'];

const caseInsensitiveComparator = (a, b) => 
  a.toLowerCase() === b.toLowerCase();

const commonItems = _.intersectionWith(letters1, letters2, caseInsensitiveComparator);

console.log(commonItems);
// Output: [ 'apple', 'BANANA' ]

Key Considerations