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: '[email protected]'
    },
    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: '[email protected]'
    },
    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: "[email protected]",
    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 ?

6
  • You have two JavaScript objects not json objects. I know this is nitpicking, but they’re different things. Commented May 29, 2020 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. Commented May 29, 2020 at 11:38
  • 1
    Does {...order1,...order2} give you what you are after? Commented May 29, 2020 at 11:38
  • Does this answer your question? Getting a diff of two json-objects Commented May 29, 2020 at 11:39
  • @evolutionxbox yes you are right, my mistake, thanks for pointing it out. Commented May 29, 2020 at 11:42

2 Answers 2

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));
Sign up to request clarification or add additional context in comments.

2 Comments

@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.
what if I only want to compare the keys instead of their values
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))

1 Comment

Your code returns also the equal fields like drink or chips

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.