2

I have two Javascript objects

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

What I need is to compare these two objects (order1 is existing and order2 is the edited data) and store the difference in a new variable named var order3. However if there is an array inside an object like the toppings array to be copied as whole with the changes.

In short the result should be

{
  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
}]
}

How can i achieve this ?

Pratyush Swain
  • 144
  • 1
  • 9
  • You have two JavaScript objects not json objects. I know this is nitpicking, but they’re different things. – evolutionxbox May 29 '20 at 11:35
  • Hi Pratyush. Your question is too broad, there are more than one ways to implement what you want. Have you tried a particular algorithm which did not work? Maybe start from there and post a question with a specific problem. – Romi Halasz May 29 '20 at 11:38
  • 1
    Does {...order1,...order2} give you what you are after? – ak85 May 29 '20 at 11:38
  • Does this answer your question? [Getting a diff of two json-objects](https://stackoverflow.com/questions/8431651/getting-a-diff-of-two-json-objects) – misss-popcorn May 29 '20 at 11:39
  • @evolutionxbox yes you are right, my mistake, thanks for pointing it out. – Pratyush Swain May 29 '20 at 11:42
  • @RomiHalasz I tried to use recursive strategy to compare and take the difference out, however in the case of array(toppings) it returned me back the keys that have difference. What I want in this case is to return back the complete array with the difference. – Pratyush Swain May 29 '20 at 11:44

2 Answers2

3

This gives you exactly what you wanted:

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));
Kamil Szot
  • 17,436
  • 6
  • 62
  • 65
  • @PratyushSwain Great! Happy to help! Please mark my answer as accepted answer. You can do it with a 'checkmark' right below the number of upvotes of this answer. – Kamil Szot May 29 '20 at 17:40
  • what if I only want to compare the keys instead of their values – VnC Nov 28 '22 at 13:09
0

I think you are looking for a diff'ing algorithm. Wrote this quick recursive function that iterates over each enumerable property of your JavaScript object (not json object) testing equality. Note that the position of arguments does affect the output

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))
Ben
  • 3,160
  • 3
  • 17
  • 34