Mike K
Mike K

Reputation: 6491

Recursion function to return the path of the differences during a deep comparison

I have the below recursion function:

const getDiff = (object, base) => {
  const changes = (object, base, path = "") => {
    return _.transform(object, function(result, value, key) {
      if (!_.isEqual(value, base[key])) {
        if (_.isObject(value) && _.isObject(base[key])) {
          if (!path) {
            path += `${key}`;
          } else {
            path += `.${key}`;
          }

          result[key] = changes(value, base[key], path);
        } else {
          if (!path) {
            path = key;
          }
          result[key] = { value, path };
        }
      }
    });
  };
  return changes(object, base);
};

I'm trying to make sure that it returns not just the properties that are different, but also the direct path of that property.

For instance, if I have,

const objA = {
  filter: {
    tag: 1
  },
  name: 'a'
}

const objB = { name: 'b' };

Then getting the diff should yield:

{
  filter: {
    value: { tag: 1 },
    path: 'filter.tag'
  },
  name: {
    value: 'a',
    path: 'name'
  }
}

But right now it returns path: 'filter' always. What am I doing wrong?


Below link for quick access to lodash for the console:

fetch('https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js')
    .then(response => response.text())
    .then(text => eval(text))

Upvotes: 0

Views: 46

Answers (1)

Estradiaz
Estradiaz

Reputation: 3563

Your current path is scoped outside of _.transform thus it will apply to all branches.

Scope it within the result of _.transform and everything is ok.

E.g.:

const getDiff = (object, base) => {
                                //changed
  const changes = (object, base, _path = "") => {
    return _.transform(object, function(result, value, key) {
      // changed
      let path = _path;
      if (!_.isEqual(value, base[key])) {
        if (_.isObject(value) && _.isObject(base[key])) {
          if (!path) {
            path += `${key}`;
          } else {
            path += `.${key}`;
          }

          result[key] = changes(value, base[key], path);
        } else {
          if (!path) {
            path = key;
          } else { // changed
            path += `.${key}`;  
          }
          result[key] = { value, path };
        }
      }
    });
  };
  return changes(object, base);
};

Upvotes: 1

Related Questions