3

I have 2 large objects to compare. I want to know if they are equal.
JSON.stringify(obj1) == JSON.stringify(obj2) does not work, because the objects are dynamically created so the order of the attributes are random.

So I wrote a isEqual() as follows.

function isEqual(ar1, ar2) {
    if(ar1 !== ar2) {
        if(typeof ar1 !== typeof ar2) {
            return false;
        }
        if(ar1 == null) {
            if(ar2 == null) {
                return true;
            }
            return false;
        }
        if(ar2 == null) {
            if(ar1 == null) {
                return true;
            }
            return false;
        }
        if(typeof ar1 !== 'object') {
            return false;
        }
        if (ar1.length !== ar2.length) {
            return false;
        }
        for(var i in ar1) {
            if(!isEqual(ar1[i], ar2[i])) {
                return false;
            }
        }
        for(var i in ar2) {
            if(!isEqual(ar1[i], ar2[i])) {
                return false;
            }
        }
    }
    return true;
}

Now if I run isEqual(obj1, obj2) the tab in chrome freezes and I am not able to close the tab. I have to wait until chrome asks me to close non responding tabs after about 10 minutes. How to solve this?

S.Babovic
  • 335
  • 5
  • 15

2 Answers2

1

Use Lodash's isEqual to do this for you.

https://lodash.com/docs/4.17.4#isEqual

Pytth
  • 4,008
  • 24
  • 29
-1

I'd like to offer my solution. Please try it with your JSON objects. in order to check if objects have a different number of fields you can use

Object.keys(ar1).length !== Object.keys(ar2).length

 function isEqual(ar1, ar2) {
    if((ar1 === null) && (ar2 === null))
        return true;


    //console.info("Type: " + typeof ar1 + ":" + typeof ar2)
    if (typeof ar1 !== typeof ar2) {
        return false;
    }
    console.info("Length: " + ar1.length + ":" + ar2.length)
    if (ar1.length !== ar2.length) {
        return false;
    }

    if((typeof ar1 === 'object') && (typeof ar2 === 'object') && (Object.keys(ar1).length !== Object.keys(ar2).length))
        return false;

    if ((typeof ar1 !== 'object') && (typeof ar2 !== 'object')) {
        //console.info("Value is not equal: " + (ar1 !== ar2))
        if (ar1 !== ar2)
            return false;
        else 
            return true;
    }
    for (var i in ar1) {
        //console.info("Values:" + ar1[i] + ":" + ar2[i])
        if (!isEqual(ar1[i], ar2[i])) {
            return false;
        }
    }
    return true;
}
var obj1 = {
    a : 1,
    b :[1, 2, 3],
    c: {a:1}

};
var obj2 = {
    a : 1,
    b : [1, 2, 3],
    c: {a:1},
    d:1
};
isEqual(obj1, obj2)
volkinc
  • 2,143
  • 1
  • 15
  • 19
  • I needed the second loop because sometimes there are some attributes in obj 2 which are not present in obj1. At first I had only one loop, but in some circumstances this `isEqual` considered two objects equal even if they weren't. – S.Babovic Aug 28 '17 at 14:32
  • Ah. i thought .arr.length should take case about. Can you give me an example? – volkinc Aug 28 '17 at 14:35
  • added check for isEqual(null,null) and null combinations that were missing – volkinc Aug 28 '17 at 14:46