-1
let baseObj =  {
    place: {city: 'Bangalore', pin: 123456},
    office: [
        { name: 'Tom', age: 22, salutation: { title: 'Mr'}}, 
        { name: 'John', age: 31, salutation: { title: 'Mr'}}
    ]
} 
let updatedObj = {
place: {city: 'Bangalore', pin: 99999},
    office: [
        { name: 'Tom', age: 22, salutation: { title: 'Mr'}},    
        { name: 'Peter', age: 16, salutation: { title: 'Mr'}},  
        { name: 'John', age: 31, salutation: { title: 'Mr'}}
        
    ]
}


expected result = {
   place: {city: 'Bangalore', pin: 99999},
   office: [
   { name: 'Peter', age: 16, salutation: { title: 'Mr'}}
   ]
}

Note: comparison can be done by finding the properties of object and values but no comparison should be done hardcoding the properties tried comparing the object but when we have an array of object i.e office, comparing with index(i.e 0,1) doesn't help as the array might not be sorted so couldn't proceed much

have tried the below code but it fails to get the desired output if the objects in an array are in different sequence as compared to the other array

ex. office1: [
        { name: 'Tom', age: 22, salutation: { title: 'Mr'}}, 
        { name: 'John', age: 31, salutation: { title: 'Mr'}}
    ]

office2: [
        { name: 'Tom', age: 22, salutation: { title: 'Mr'}},    
        { name: 'Peter', age: 16, salutation: { title: 'Mr'}},  
        { name: 'John', age: 31, salutation: { title: 'Mr'}}
        
    ]

  function findDiff(obj1, obj2) {
    var diffObj = Array.isArray(obj2) ? [] : {}
    Object.getOwnPropertyNames(obj2).forEach(function(prop) {
        if(prop !=='lenght' ){
        if (typeof obj2[prop] === 'object') {
            diffObj[prop] = obj1[prop]== undefined? obj2[prop]: findDiff(obj1[prop], obj2[prop])
            if (Array.isArray(diffObj[prop]) && Object.getOwnPropertyNames(diffObj[prop]).length === 1 || Object.getOwnPropertyNames(diffObj[prop]).length === 0) {
                delete diffObj[prop]
            }
        }} else if(prop !=='lenght') {
        
        if(obj1[prop] !== obj2[prop]){
            diffObj[prop] = obj2[prop]
            }
        }
    });
    return diffObj
}

akh
  • 1
  • 1

1 Answers1

0

This compare function seems to achieve exactly what you want :

const baseObj =  {"grade":"A","queue":"1","myCollections":{"myCollection":[{"commonCollection":[{"winterCollection":[{"name":"ICE","isChilled":"true"}]}]}]},"remarks":{"remark":[{"name":"GOOD","category":"A","text":{"value":"Very Good"},"indicator":"good"}]}}

const updatedObj = {"grade":"A","queue":"1","myCollections":{"myCollection":[{"commonCollection":[{"winterCollection":[{"name":"ICE","isChilled":"true"},{"code":"SNOW","isChilled":"true"}]}]}]},"remarks":{"remark":[{"name":"GOOD","category":"A","text":{"value":"Very Good"},"indicator":"good"},{"name":"BEST","text":{"value":"Test"},"category":"O","indicator":"outstanding"}]}}

const compare = (a, b, allObj = true) => {
    if (typeof a !== 'object') return a === b ? null : b

    if (Array.isArray(a)) {
        const arr = []

        b.forEach(e => {
            if (a.every(el => compare(el, e, true) !== null))
                arr.push(e)
        });

        return arr.length === 0 ? null : arr
    } else {
        const keys = Object.keys(b) // assuming a and b have the same properties
        const obj = allObj ? b : {}
        let changed = false
    
        keys.map(key => {
            const compared = compare(a[key], b[key], true)

            if (compared) {
                obj[key] = compared
                changed = true
            }
        })

        return changed ? obj : null
    }
}

const expectedResult = {"grade":"A","queue":"1","myCollections":{"myCollection":[{"commonCollection":[{"winterCollection":[{"code":"SNOW","isChilled":"true"}]}]}]},"remarks":{"remark":[{"name":"BEST","text":{"value":"Test"},"category":"O","indicator":"outstanding"}]}}

const result = compare(baseObj, updatedObj)
console.log(result)
console.log(expectedResult)

console.log(JSON.stringify(result) === JSON.stringify(expectedResult))

PS: I compared each pair but it is O(n^2). The best way is if you had an id property on every of array children.

Lucasbk38
  • 499
  • 1
  • 14
  • please try with baseObj={"grade":"A","queue":"1","myCollections":{"myCollection":[{"commonCollection":[{"winterCollection":[{"name":"ICE","isChilled":"true"}]}]}]},"remarks":{"remark":[{"name":"GOOD","category":"A","text":{"value":"Very Good"},"indicator":"good"}]}} – akh Nov 13 '22 at 17:53
  • updatedObj={"grade":"A","queue":"1","myCollections":{"myCollection":[{"commonCollection":[{"winterCollection":[{"name":"ICE","isChilled":"true"},{"code":"SNOW","isChilled":"true"}]}]}]},"remarks":{"remark":[{"name":"GOOD","category":"A","text":{"value":"Very Good"},"indicator":"good"},{"name":"BEST","text":{"value":"Test"},"category":"O","indicator":"outstanding"}]}} – akh Nov 13 '22 at 17:55
  • thanks for your solution, sorry typo from my end expected result={"myCollections":{"myCollection":[{"commonCollection":[{"winterCollection":[{"code":"SNOW","isChilled":"true"}]}]}]},"remarks":{"remark":[{"name":"BEST","text":{"value":"Test"},"category":"O","indicator":"outstanding"}]}} – akh Nov 14 '22 at 01:58
  • If you don’t want the unchanged properties to show on the root, you can specify it as the last arg : `compare(baseObj, updatedObj, false)` – Lucasbk38 Nov 14 '22 at 09:05