比较嵌套对象并使用 Javascript 在新对象中保存差异

Posted

技术标签:

【中文标题】比较嵌套对象并使用 Javascript 在新对象中保存差异【英文标题】:Compare Nested Objects and save difference in new object using 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 是的,你是对的,我的错误,感谢您指出。 【参考方案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))

【讨论】:

您的代码还返回相同的字段,例如 drinkchips【参考方案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 太棒了!乐意效劳!请将我的答案标记为已接受的答案。您可以在此答案的赞成票数正下方打一个“复选标记”。

以上是关于比较嵌套对象并使用 Javascript 在新对象中保存差异的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript 在新窗口中检查和对象并显示特性和方法

javascript - 如果在子对象中找到值,则搜索嵌套对象数组并返回父对象[重复]

javascript 映射,修改嵌套道具,并保留整个对象

将嵌套的 JSON 对象展平并排序到 javascript 中的数组中

循环嵌套对象javascript

JavaScript - 编辑嵌套对象