如何获得深度差异2对象

问题描述 投票:0回答:2

我有一个像下面这样的对象。如果我改变它的数量,我可以发现与“窗帘”的区别。但在这种情况下,它不能与我的功能一起工作。我希望我的结果是元素的所有属性都有属性更改

obj1 = {
  sofa: [
    {
      name: 'leather',
      typeSofa: [
        {
          name: 'type1',
          text: 'type1',
          quantity: 1
        },
        {
          name: 'type2',
          text: 'type2',
          quantity: 1
        }
      ],
      stool: [
        {
          name: 'type1',
          text: 'type1',
          quantity: 1
        },
        {
          name: 'type2',
          text: 'type2',
          quantity: 1
        }
      ]
    },
    {
      name: 'fabric',
      typeSofa: [
        {
          name: 'type1',
          text: 'type1',
          quantity: 1
        }
      ],
      stool: [
        {
          name: 'type1',
          text: 'type1',
          quantity: 1
        },
        {
          name: 'type2',
          text: 'type2',
          quantity: 1
        }
      ]
    }
  ],
  curtain: {
    dryclean: [{
      name: 'text1',
      text: 'text1',
      quantity; 1
    }];
  }
}

obj2 = {
  sofa: [
    {
      name: 'leather',
      typeSofa: [
        {
          name: 'type1',
          text: 'type1',
          quantity: 2
        },
        {
          name: 'type2',
          text: 'type2',
          quantity: 1
        }
      ],
      stool: [
        {
          name: 'type1',
          text: 'type1',
          quantity: 1
        },
        {
          name: 'type2',
          text: 'type2',
          quantity: 1
        }
      ]
    },
    {
      name: 'fabric',
      typeSofa: [
        {
          name: 'type1',
          text: 'type1',
          quantity: 1
        }
      ],
      stool: [
        {
          name: 'type1',
          text: 'type1',
          quantity: 1
        },
        {
          name: 'type2',
          text: 'type2',
          quantity: 1
        }
      ]
    }
  ],
  curtain: {
    dryclean: [
      {
        name: 'text1',
        text: 'text1',
        quantity; 1
      }
    ];
  }
}

在 obj2 中我只是改变数量:2 我怎样才能使用 js 或 lodash 得到结果

result = {
  sofa: [
    {
      name: 'leather',
      typeSofa: [
        {
          name: 'type1',
          text: 'type1'
          quantity: 2
        }
      ]
    }
  ]
}
const findDifferences = (obj1, obj2) => {
    // Find the keys that are in both objects
    const keys = _.intersection(Object.keys(obj1), Object.keys(obj2));

    // Iterate through the keys
    return keys.reduce((diff, key) => {
      const val1 = obj1[key];
      const val2 = obj2[key];

      // If the values are arrays, compare them using _.differenceWith() and recursion
      if (_.isArray(val1) && _.isArray(val2)) {
        diff[key] = _.differenceWith(val2, val1, _.isEqual);
        if (diff[key].length === 0) delete diff[key];
      }
      // If the values are objects, recursively call findDifferences() on them
      else if (_.isObject(val1) && _.isObject(val2)) {
        const nestedDiff = findDifferences(val1, val2);
        if (!_.isEmpty(nestedDiff)) diff[key] = nestedDiff;
      }
      // Otherwise, compare the values directly using _.isEqual()
      else if (!_.isEqual(val1, val2)) {
        diff[key] = val2;
      }

      return diff;
    }, {});
  };

我期望我的函数有这样的结果

result = {
  sofa: [
    {
      name: 'leather',
      typeSofa: [
        {
          name: 'type1',
          text: 'type1'
          quantity: 2
        }
      ]
    }
  ]
}
javascript lodash deep-diff
2个回答
0
投票
import _ from "lodash";

const obj1 = {
  sofa: [
    {
      name: 'leather',
      typeSofa: [
        {
          name: 'type1',
          text: 'type1',
          quantity: 1
        },
        {
          name: 'type2',
          text: 'type2',
          quantity: 1
        }
      ],
      stool: [
        {
          name: 'type1',
          text: 'type1',
          quantity: 1
        },
        {
          name: 'type2',
          text: 'type2',
          quantity: 1
        }
      ]
    },
    {
      name: 'fabric',
      typeSofa: [
        {
          name: 'type1',
          text: 'type1',
          quantity: 1
        }
      ],
      stool: [
        {
          name: 'type1',
          text: 'type1',
          quantity: 1
        },
        {
          name: 'type2',
          text: 'type2',
          quantity: 1
        }
      ]
    }
  ],
  curtain: {
    dryclean: [{
      name: 'text1',
      text: 'text1',
      quantity: 1
    }]
  }
}

const obj2 = {
  sofa: [
    {
      name: 'leather',
      typeSofa: [
        {
          name: 'type1',
          text: 'type1',
          quantity: 2
        },
        {
          name: 'type2',
          text: 'type2',
          quantity: 1
        }
      ],
      stool: [
        {
          name: 'type1',
          text: 'type1',
          quantity: 1
        },
        {
          name: 'type2',
          text: 'type2',
          quantity: 1
        }
      ]
    },
    {
      name: 'fabric',
      typeSofa: [
        {
          name: 'type1',
          text: 'type1',
          quantity: 1
        }
      ],
      stool: [
        {
          name: 'type1',
          text: 'type1',
          quantity: 1
        },
        {
          name: 'type2',
          text: 'type2',
          quantity: 1
        }
      ]
    }
  ],
  curtain: {
    dryclean: [
      {
        name: 'text1',
        text: 'text1',
        quantity: 1
      }
    ]
  }
}

const findDifferences  = (obj1, obj2) => {
  return _.transform(obj2, (result, value, key) => {
    if (!_.isEqual(value, obj1[key])) {
      result[key] = _.isObject(value) && _.isObject(obj1[key]) ? findDifferences (obj1[key], value) : value;
      if (_.isObject(value)) {
        const diffKeys = _.difference(_.keys(value), _.keys(obj1[key]));
        if (diffKeys.length > 0) {
          result[key] = value;
        }
      }
    }
  });
};

const result = findDifferences (obj1, obj2);

console.log(JSON.stringify(result));

结果:

{
  "sofa": [
    {
      "typeSofa": [
        {
          "quantity": 2
        }
      ]
    }
  ]
}

结果将是所有更改的键,例如名称、文本或数量。例如,如果 obj2 的文本值也不同于 obj1,它也会提供此键。我的重要建议是为每个项目设置一个唯一的 ID,但在这种情况下,代码需要不同。

您说:“结果将是元素的所有属性都有属性更改”

代码实际上就是这样做的,这是你需要的吗?


0
投票

我之前的回答不是 OP 想要的。我找到了解决方案。

const obj1 = { *your data* }
const obj2 = { *your data* }

const result = { sofa: [] };

_.forEach(obj2.sofa, (sofa, i) => {
  _.forEach(sofa.typeSofa, (typeSofa, j) => {
    const typeSofa2 = obj1.sofa[i].typeSofa[j];
    if (typeSofa.quantity !== typeSofa2.quantity || typeSofa.name !== typeSofa2.name || typeSofa.text !== typeSofa2.text) {
      result.sofa.push({
        name: sofa.name,
        typeSofa: [
          {
            name: typeSofa.name,
            text: typeSofa.text,
            quantity: typeSofa.quantity
          }
        ]
      });
    }
  });
});

console.log(JSON.stringify(result));

结果:

{
  "sofa": [
    {
      "name": "leather",
      "typeSofa": [
        {
          "name": "type1",
          "text": "type1",
          "quantity": 2
        }
      ]
    }
  ]
}

如果您还想在某个对象上寻找差异,则必须添加这行代码

// Change result to this
const result = { sofa: [], curtain: { dryclean: [] } };

// Add these lines below
_.forEach(obj2.curtain.dryclean, (curtain, i) => {
  if (curtain.quantity !== obj1.curtain.dryclean[i].quantity || curtain.name !== obj1.curtain.dryclean[i].name || curtain.text !== obj1.curtain.dryclean[i].text) {
    result.curtain.dryclean.push({
      name: curtain.name,
      text: curtain.text,
      quantity: curtain.quantity
    });
  }
});
© www.soinside.com 2019 - 2024. All rights reserved.