Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: Add possibility to exclude/omit keys when comparing objects #92

Open
karlitos opened this issue Dec 15, 2022 · 2 comments

Comments

@karlitos
Copy link

I encountered the necessity to compare some generated data with test data, where those data sets include dynamically generated id values nested in different levels. So the goal was to test the object for equality by ignoring/ommiting those id_ keys.

E.G.

// test for equality but ignore the values of id
{
  id: 1234,
  a: 'foo',
  b: {
    id: 45678
    c:  'bar'
  }

}

I cerated my own - much simpler deepEql_ function

const deepEql = (a: unknown, b: unknown, omitKeys: string[] = []): boolean => {
    if (a === b) return true;

    omitKeys.forEach(key => delete a[key]);
    omitKeys.forEach(key => delete b[key]);

    if (typeof a !== 'object' || typeof b !== 'object' || a == null || b == null) return false;

    const keysA = Object.keys(a);
    const keysB = Object.keys(b);

    if (keysA.length !== keysB.length) return false;

    // eslint-disable-next-line no-restricted-syntax
    for (const key of keysA) {
      if (!keysB.includes(key)) return false;

      if (typeof a[key] === 'function' || typeof b[key] === 'function') {
        if (a[key].toString() !== b[key].toString()) return false;
      } else if (!this.deepEql(a[key], b[key], omitKeys)) return false;
    }

    return true;
  }

which works in my case, but I would love to see the possibility to specify which keys to exclude in the deep-eql api which seems obviously much more reliable than my solution

@keithamus
Copy link
Member

Thanks for the issue @karlitos.

With the current API you can pass in a custom comparator function which gets called on every value so that you can filter it out as you see fit. You could write a custom comparator that deletes the keys like your code does, but it can rely on the rest of the of the internals of this library.

I think the comparator provides enough flexibility with the API to allow for the functionality you’re after.

@karlitos
Copy link
Author

You could write a custom comparator that deletes the keys like your code does, but it can rely on the rest of the of the internals of this library.

Could you elaborate more on this please ? So basically the custom comparator be a function which will accept the leftHandOperand, rightHandOperand as parameters, performing the

omitKeys.forEach(key => delete a[key]);
omitKeys.forEach(key => delete b[key]);

and returning the value of deepEqual for them ? But how do I pass the custom comparator to the deepEqual from within the custom comparator ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants