首页 > 解决方案 > 在深度比较期间返回差异路径的递归函数

问题描述

我有以下递归函数:

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);
};

我试图确保它不仅返回不同的属性,还返回该属性的直接路径。

例如,如果我有,

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

const objB = { name: 'b' };

然后得到差异应该产生:

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

但现在它path: 'filter'总是返回。我究竟做错了什么?


以下链接可快速访问控制台的 lodash:

fetch('https://cdn.jsdelivr.net/npm/lodash@4.17.4/lodash.min.js')
    .then(response => response.text())
    .then(text => eval(text))

标签: javascript

解决方案


您当前的路径范围之外,_.transform因此它将适用于所有分支。

将其范围限定在结果范围内_.transform,一切正常。

例如:

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);
};

推荐阅读