【问题标题】:Javascript : Find the difference between 2 objects and return only keys [closed]Javascript:查找2个对象之间的差异并仅返回键[关闭]
【发布时间】:2019-12-31 06:19:04
【问题描述】:

我想找出 2 个对象的不同之处,只获取其更新的键并返回它们。

我使用过deep-diffobject-diff npm 库。但它不起作用。

我该如何解决这个问题?

我只想要正在更改的键。无论是更新、添加还是删除。

下面是我试过的代码。

const diff = require("deep-object-diff").diff;

let oldData = {
  name: 'ABC',
  age: 20,
  marks: [20, 50, 40, 30],
  hobbies: ['playing', 'reading']
}

let newData = {
  name: 'XYZ',
  age: 20,
  marks: [20, 40, 80, 30]
}

console.log(diff(oldData, newData));

所以我想要像 namemarkshobbies 这样更改的键。

任何帮助都会很棒。

谢谢。

【问题讨论】:

  • 你想要对象中键的差异,还是所有差异,或者更新时的变化删除等?
  • 我只想要删除、更新或添加的密钥。因为从前端,我将发送 update 数组,其中仅包含更新或添加或删除的那些键。

标签: javascript object difference


【解决方案1】:
let setA = new Set(Object.values(oldData))
let setB=  new Set(Object.values(newData)) 

这些将使用您的旧值和新值创建数组,然后将它们设为Set。借助 Set 方法,我们可以找到不同之处

function difference(setA, setB) {
    let _difference = new Set(setA)
    for (let elem of setB) {
        _difference.delete(elem)
    }
    return _difference
}
let differenceArray = Array.from(_difference); // making Array from a Set
let differenceObject = Object.assign({},differenceArray)  

现在我们创建了一个对象,它的键只是索引(0,1,2..etc),值是差异数组的项目。你得到了改变的值,现在我们需要在开始时在对象中找到属于这些值的键(oldData)

 let oldData = {
  name: 'ABC',
  age: 20,
  marks: [20, 50, 40, 30],
  hobbies: ['playing', 'reading']
}

let newData = {
  name: 'XYZ',
  age: 20,
  marks: [20, 40, 80, 30]
}


let setA = new Set(Object.values(oldData))
let setB=  new Set(Object.values(newData)) 


function difference(setA, setB) {
    let _difference = new Set(setA)
    for (let elem of setB) {
        _difference.delete(elem)
    }
    return _difference
}
let differenceArray = Array.from(difference(setA, setB)); // making Array from a Set
let differenceObject = Object.assign({},differenceArray)  


const keysArray = [];
for (let value of Object.values(differenceArray)) {
  keysArray.push(Object.keys(oldData).filter(key => oldData[key] === value));
}


console.log(keysArray)  // 0: ["name"] 1: ["marks"] 2: ["hobbies"]

keysArray 是由更改的键组成的数组

【讨论】:

  • 感谢您的回答。它不工作。
  • @XperiaReno 我编辑了答案。你现在可以试试吗
  • 不工作了。我得到所有带键的数组。我的对象可能会有所不同。所以我需要处理任何发生的情况。我在问题中设置的示例只是一个虚拟示例。不是真的。
  • 我认为这个解决方案是一个很好的起点,但是您还需要处理嵌套对象。
  • @John 你说的有道理,我再看看
【解决方案2】:

如果我们假设对象不会有嵌套对象,我会从对象中提取键,像这样在一个单独的数组中

const allKeys = [...Object.keys(oldData),...Object.keys(newData)];
// TODO remove duplicate keys

然后我会比较每个键在两个对象中的值,并将具有差异的键添加到数组中

const changedKeys = [];
allKeys.forEach(key => {
 if(oldObj.hasOwnProperty(key) && newObj.hasOwnProperty(key)) {
  if(Array.isArray(oldObj[key])){
    // TODO loop the arrays and compare the difference
    // Wee need to do that because ['2'] === ['2'] means false.
  } else if(oldObj[key] !== newObj[key]) {
    changedKeys.push(key);
  }
 } else { // means the key was deleted 
  changedKeys.push(key);
 }
});

那么你的结果就是 changedKeys 数组。

注意:我在没有测试的情况下写了这个,可能存在错误。此外,如果对象包含其他对象,我们将需要考虑递归策略。

【讨论】:

  • 感谢您的回答。对象可能会有所不同。对象内部可能有数组。也有嵌套对象。
【解决方案3】:

您可以使用for in 语法。

for (let prop in first_obj){
    if(prop !== second_obj){
    return [Object.keys(first_obj),Object.keys(second_obj)]
  }
}

此函数的返回将是或未定义 - 它们相等,或数组旁边有两个数组 - 每个数组 - 一个对象的键的数组

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-04
    • 2020-04-02
    • 2017-12-21
    • 2019-08-11
    • 2013-09-18
    • 2017-09-29
    相关资源
    最近更新 更多