【问题标题】:Compare Nested Objects and save difference in new object using Javascript比较嵌套对象并使用 Javascript 在新对象中保存差异
【发布时间】:2020-09-16 23:11:48
【问题描述】:

我有两个 Javascript 对象

var order1 = {
    sandwich: 'tuna',
    chips: true,
    drink: 'soda',
    order: 1,
    toppings: [{VendorNumber: 18, PreferredFlag: false, SupportedFlag: true}, {VendorNumber: 19, PreferredFlag: false, SupportedFlag: true}, {VendorNumber: 20, PreferredFlag: false, SupportedFlag: true}],
    details: {
        name: 'Chris',
        phone: '555-555-5555',
        email: 'no@thankyou.com'
    },
    otherVal1: '1'
};

var order2 = {
    sandwich: 'turkey',
    chips: true,
    drink: 'soda',
    order: 2,
    toppings: [{VendorNumber: 18, PreferredFlag: false, SupportedFlag: true}, {VendorNumber: 19, PreferredFlag: false, SupportedFlag: false}, {VendorNumber: 20, PreferredFlag: true, SupportedFlag: true}],
    details: {
        name: 'Jon',
        phone: '(555) 555-5555',
        email: 'yes@please.com'
    },
    otherVal1: '2'
};

我需要比较这两个对象(order1 是存在的,order2 是编辑过的数据)并将差异存储在一个名为 var order3 的新变量中。但是,如果对象内部有一个数组,例如 toppings 数组,则要与更改一起整体复制。

简而言之,结果应该是

{
  details: {
    email: "yes@please.com",
    name: "Jon",
    phone: "(555) 555-5555"
  },
  order: 2,
  otherVal1: "2",
  sandwich: "turkey",
  toppings: [{
  PreferredFlag: false,
  SupportedFlag: true,
  VendorNumber: 18
}, {
  PreferredFlag: false,
  SupportedFlag: false,
  VendorNumber: 19
}, {
  PreferredFlag: true,
  SupportedFlag: true,
  VendorNumber: 20
}]
}

我怎样才能做到这一点?

【问题讨论】:

  • 你有两个 JavaScript 对象而不是 json 对象。我知道这是吹毛求疵,但它们是不同的东西。
  • 你好,Pratyush。你的问题太宽泛了,有不止一种方法可以实现你想要的。您是否尝试过不起作用的特定算法?也许从那里开始并发布一个具有特定问题的问题。
  • {...order1,...order2} 能满足您的需求吗?
  • 这能回答你的问题吗? Getting a diff of two json-objects
  • @evolutionxbox 是的,你是对的,我的错误,感谢您指出。

标签: javascript json angular typescript object


【解决方案1】:

我认为您正在寻找一种差异算法。编写了这个快速递归函数,它遍历 JavaScript 对象(不是 json 对象)的每个可枚举属性来测试相等性。请注意,参数的位置确实会影响输出

function diff(obj1, obj2) {
    if (typeof obj1 === "object") {
        const obj = {};
        for (const prop in obj1) {
            if (diff(obj1[prop], obj2[prop])) {
                obj[prop] = obj1[prop]
            }
        }
        return obj
    } else {
        return obj1 !== obj2;
    }
}

console.log(diff(order2, order1))

【讨论】:

  • 您的代码还返回相同的字段,例如 drink 或 chips
【解决方案2】:

这正是你想要的:

function diff(tgt, src) {

    if (Array.isArray(tgt)) { // if you got array
        return tgt; // just copy it
    }

    // if you got object
    var rst = {};
    for (var k in tgt) { // visit all fields
        if (typeof src[k] === "object") { // if field contains object (or array because arrays are objects too)
            rst[k] = diff(tgt[k], src[k]); // diff the contents
        } else if (src[k] !== tgt[k]) { // if field is not an object and has changed
            rst[k] = tgt[k]; // use new value
        }
        // otherwise just skip it
    }
    return rst;
}
console.log(diff(order2, order1));

【讨论】:

  • @PratyushSwain 太棒了!乐意效劳!请将我的答案标记为已接受的答案。您可以在此答案的赞成票数正下方打一个“复选标记”。
猜你喜欢
  • 2019-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-03
  • 2020-04-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多