I'm trying to do an equality comparison ignoring undefined values using lodash.

I'd expect the following to work:

console.log(
  isEqualWith(request.body, actualRequest.body.json, (a, b) => {
    console.log(a, b, a === undefined && b === undefined ? true : undefined
    );
    return a === undefined && b === undefined ? true : undefined;
  })
);

However, the console output fails on the 'first' comparison (of the whole objects), even though the customizer returns undefined. Here's the output:

{ item1: undefined, item2: 'test'} { item2: 'test' } undefined
false

It's never comparing anything except the first object. I'd expect an output like:

{ item1: undefined, item2: 'test'} { item2: 'test' } undefined
undefined undefined true
'test' 'test' undefined
true

As, given the customizer returned undefined for the first check, then it would have gone through the fields of the object and performed the customzer check on those.

1 Answers

1
Ori Drori On Best Solutions

When you return undefined in the case of object, the method _.isEqualWith() makes many comparison to decide if the objects are equal or not. It actually checks if the number of keys is the same in both objects, which fails in your case. If it had the same number of keys, it would fail when making hasOwnProperty checks.

To make a partial comparison that ignores undefined values, use _.isMatch(), which actually uses the same logic but ignores the length (and other checks) by setting the bitmask for COMPARE_PARTIAL_FLAG.

const o1 = { item1: undefined, item2: 'test' } 
const o2 = { item2: 'test' }

const result = _.isMatch(o1, o2)

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>