Javascript - deepEqual Comparison

后端 未结 8 1280
囚心锁ツ
囚心锁ツ 2020-12-05 05:21

Question (From Eloquent Javascript 2nd Edition, Chapter 4, Exercise 4):

Write a function, deepEqual, that takes two values and returns true only if th

相关标签:
8条回答
  • 2020-12-05 05:55

    I am quite new to JS but this is the way I solved it:

    function deepEqual(obj1, obj2) {
    if (typeof obj1 === "object" && typeof obj2 === "object") {
        let isObjectMatch = false;
        for (let property1 in obj1) {
            let isPropertyMatch = false;
            for (let property2 in obj2) {
                if (property1 === property2) {
                    isPropertyMatch = deepEqual(obj1[property1], obj2[property2])
                }
    
                if(isPropertyMatch){
                    break;
                }
            }
    
            isObjectMatch  = isPropertyMatch;
    
            if (!isObjectMatch) {
                break;
            }
        }
    
        return isObjectMatch;
    } else {
        return obj1 === obj2;
    }
    }
    

    And here are my tests:

    var obj = {here: {is: "an"}, object: 2};
    console.log(deepEqual(obj, obj));
    // → true
    console.log(deepEqual(obj, {here: 1, object: 2}));
    // → false
    console.log(deepEqual(obj, {here: {is: "an"}, object: 2}))
    // → true
    console.log(deepEqual(obj, {object: 2, here: {is: "an"}}));
    // → true
    console.log(deepEqual(obj, {object: 1, here: {is: "an"}}));
    // → false
    console.log(deepEqual(obj, {objectt: 2, here: {is: "an"}}));
    // → false
    console.log(deepEqual(2, 2));
    // → true
    console.log(deepEqual(2, 3));
    // → false
    console.log(deepEqual(2, null));
    // → false
    console.log(deepEqual(null, null));
    // → false
    console.log(deepEqual(obj, null));
    // → false
    
    0 讨论(0)
  • 2020-12-05 06:00

    Feel that this version is a bit more readable (easier to comprehend). The logic is very similar with the top answer though. (ES6 this time)

    function deepEqual(obj1, obj2) {
    
        if(obj1 === obj2) // it's just the same object. No need to compare.
            return true;
    
        if(isPrimitive(obj1) && isPrimitive(obj2)) // compare primitives
            return obj1 === obj2;
    
        if(Object.keys(obj1).length !== Object.keys(obj2).length)
            return false;
    
        // compare objects with same number of keys
        for(let key in obj1)
        {
            if(!(key in obj2)) return false; //other object doesn't have this prop
            if(!deepEqual(obj1[key], obj2[key])) return false;
        }
    
        return true;
    }
    
    //check if value is primitive
    function isPrimitive(obj)
    {
        return (obj !== Object(obj));
    }
    

    By the way, there is a cheater version of deep equal which works like a charm)) However, it's approximately 1.6 times slower.

    As noticed by zero298, this approach is sensitive to the properties ordering and shouldn't be taken seriously

    function cheatDeepEqual(obj1, obj2)
    {
        return JSON.stringify(obj1) === JSON.stringify(obj2);
    }
    
    0 讨论(0)
提交回复
热议问题