0

The following is working code. The question is specifically about refactoring to provide the string for property name used to compare by isSame. Perhaps better renamed to isPropValueSame.

import * as _ from 'lodash';

const diff = _.differenceWith(sourceList, comparatorList, this.isSame);

isSame = (objA: any, objB: any) => (_.has(objA, 'id') && _.has(objB, 'id') ? objA['id'] === objB['id'] : false);

Looking to pass field/prop name string like this.isSame('id'));

objA and objB would be the items from lists: sourceList and comparatorList and lists might look like:

const sourceList = [
    { id: 1, prop2: { prop21: someValue }, prop3: prop3Value },
    { id: 2, prop2: { prop21: someValue }, prop3: prop3Value },
    { id: 3, prop2: { prop21: someValue }, prop3: prop3Value },
];
const comparatorList = [
    { id: 1, prop2: { prop21: someValue }, prop3: prop3Value },
    //{ id: 2, prop2: { prop21: someValue }, prop3: prop3Value },
    { id: 3, prop2: { prop21: someValue }, prop3: prop3Value },
];

With above test case data (note comparatorList has second item commented out), then the output of comparator would return the item where id equals 2 because it does not find it during comparison by delegate function isSame.

Adam Cox
  • 3,341
  • 1
  • 36
  • 46
  • What are `objA` and `objB` supposed to be then? – kelsny Apr 13 '23 at 14:17
  • [Closure](https://www.freecodecamp.org/news/javascript-closures-explained-with-example/) that accepts prop name and returns isSame(a, b) function? – jarmod Apr 13 '23 at 14:21
  • I'd try provide the types of objA and objB. Without that typescript has no info to infer the return type. – rustyBucketBay Apr 13 '23 at 14:23
  • @rustyBucketBay it doesn't make a difference here. Code works as provided. The question is specifically about refactoring to provide the `field name` as string to the delegate func. – Adam Cox Apr 13 '23 at 14:39

2 Answers2

1

Not sure if you're looking for more than just a closure around the key – doesn't seem like type-safety is a concern for you so could be as simple as:

const isSame = (key: string) => (objA: unknown, objB: unknown) =>
  _.has(objA, key) && _.has(objB, key) && _.get(objA, key) === _.get(objB, key);

Sandbox

If you can live without having type checking on the key then that would suffice, but if you need it then I'd refer you to this previous answer on recursive access paths.

motto
  • 2,888
  • 2
  • 2
  • 14
  • I think the `typescript` tag gave the wrong impression of the sort of answer you were looking for. – motto Apr 13 '23 at 14:48
  • awarded because you're first AND provide link to recursive paths. i ask questions for the learning. thanks again!! – Adam Cox Apr 13 '23 at 14:52
1

One option is to use a closure to which you pass the prop/attribute of interest:

const isSame = (prop) => {
  const issame = (a, b) => (_.has(a, prop) && _.has(b, prop) ? a[prop] === b[prop] : false);
  return issame;
};

const someValue = 42;
const prop3Value = 3;

const sourceList = [
  { id: 1, prop2: { prop21: someValue }, prop3: prop3Value },
  { id: 2, prop2: { prop21: someValue }, prop3: prop3Value },
  { id: 3, prop2: { prop21: someValue }, prop3: prop3Value },
];
const comparatorList = [
  { id: 1, prop2: { prop21: someValue }, prop3: prop3Value },
  // { id: 2, prop2: { prop21: someValue }, prop3: prop3Value },
  { id: 3, prop2: { prop21: someValue }, prop3: prop3Value },
];

console.log(_.differenceWith(sourceList, comparatorList, isSame("id")));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
jarmod
  • 71,565
  • 16
  • 115
  • 122
  • can't award twice. upvoted for effort. thanks! – Adam Cox Apr 13 '23 at 14:55
  • No worries. I wasted time between adding the initial comment on closures and getting a code snippet to work before posting an answer. My loss! This is a primary use case for closures, though there are [others](https://www.frontendmag.com/insights/advantages-of-closures-in-javascript/). – jarmod Apr 13 '23 at 15:02
  • yes. i didn't even think (or realize) i could stack the closures. haha! i am glad i asked. – Adam Cox Apr 13 '23 at 15:28