eloquent - Deep Compare JavaScript function - Stack Overflow

I'm working my way through the 3rd edition of Eloquent JavaScript and although I've seen one

I'm working my way through the 3rd edition of Eloquent JavaScript and although I've seen one or two various answers on SO that seem almost identical in execution logic to mine that work mine just doesnt seem to no matter how I tweek it.

THE GOAL: create a deep parison function that can pare two objects and determine based on their properties if theyre different instances of the same type of object (same keys and values) regardless of reference...

Can anyone spot the bug in my code?

function deepEqual(a,b){
  if((typeof a=='object'&& a!=null)&&(typeof b=='object'&& b!=null)){
   if(Object.keys(a).length != Object.keys(b).length){return false}    
    for(let key in a){
        if(a[key]==b[key]){
          if(!deepEqual(a[key],b[key])){return false}
        }else{
          return false
        }
    }
   return true
  }else if(a!==b){return false}

  else{return true}
}

var obj = {here: {is: "an"}, object: 2};
console.log(deepEqual(obj, obj));
// → true (reads true currently)
console.log(deepEqual(obj, {here: 1, object: 2}));
// → false (reads false currently)
console.log(deepEqual(obj, {here: {is: "an"}, object: 2}));
// → true (reads false currently)

I'm working my way through the 3rd edition of Eloquent JavaScript and although I've seen one or two various answers on SO that seem almost identical in execution logic to mine that work mine just doesnt seem to no matter how I tweek it.

THE GOAL: create a deep parison function that can pare two objects and determine based on their properties if theyre different instances of the same type of object (same keys and values) regardless of reference...

Can anyone spot the bug in my code?

function deepEqual(a,b){
  if((typeof a=='object'&& a!=null)&&(typeof b=='object'&& b!=null)){
   if(Object.keys(a).length != Object.keys(b).length){return false}    
    for(let key in a){
        if(a[key]==b[key]){
          if(!deepEqual(a[key],b[key])){return false}
        }else{
          return false
        }
    }
   return true
  }else if(a!==b){return false}

  else{return true}
}

var obj = {here: {is: "an"}, object: 2};
console.log(deepEqual(obj, obj));
// → true (reads true currently)
console.log(deepEqual(obj, {here: 1, object: 2}));
// → false (reads false currently)
console.log(deepEqual(obj, {here: {is: "an"}, object: 2}));
// → true (reads false currently)
Share Improve this question edited Sep 25, 2018 at 10:05 icedwater 4,9063 gold badges38 silver badges53 bronze badges asked Feb 11, 2018 at 5:17 user16801user16801 551 silver badge6 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 5

The bug was here:

if (a[key] == b[key])

if they're objects the condition may return false even if they're "equal".

function deepEqual(a, b) {
  if (a && b && typeof a == 'object' && typeof b == 'object') {
    if (Object.keys(a).length != Object.keys(b).length) return false;
    for (var key in a) if (!deepEqual(a[key], b[key])) return false;
    return true;
  } else return a === b
}

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 

Looks like you just need to tweak your for-loop logic to catch objects like so (using your own logic):

for(let key in a){
  let aValue = a[key]
  let bValue = b[key]

  if (typeof aValue == 'object' && typeof bValue == 'object') {
    // catches nested objects and recursively assesses deep equality
    if(!deepEqual(aValue, bValue)) return false
  }
  else if (aValue !== bValue) {
    // if the values are not objects, catches if they are not equal
    return false
  }
}

You can play with this, here: https://jsbin./wotapezuwo/edit?js,console

You can use below function to deep pare values

 function deepCompare(a,b){
       // shallow check
        if (a === b) return true;
    
        // determining types
        const typeA = Object.prototype.toString.call(a);
        const typeB = Object.prototype.toString.call(b);
    
        // if types are not equal
        if (typeA != typeB) return false;
    
        // paring if object
        if (typeA === '[object Object]') {
            if (Object.keys(a) !== Object.keys(b)) return false;
            for (let key in a)
                if (!deepCompare(a[key], b[key])) return false;
            return true;
        }
    
        // paring if array
        else if (typeA === '[object Array]') {
            if (a.length !== b.length) return false;
            for (let i = 0; i < a.length; i++)
                if (!deepCompare(a[i], b[i])) return false;
            return true;
        }
    
        // paring if map 
        else if (typeA === "[object Map]") {
            if (a.keys().length !== b.keys().length) return false;
            for (let key of a.keys())
                if (!deepCompare(a.get(key), b.get(key))) return false;
            return true;
        }
      
        // paring if sets
        else if (typeA === '[object Set]') {
            let x = [...a], y = [...b];
            return deepCompare(x, y);
        }
      
        // null & undefined checks
        else if (typeA === '[object Undefined]' || typeA === '[object Null]')
            return true;
    
        // nothing matched 
        return false;
    }

let a=[1,'a',{x:[1,2,3], y: new Map([['a',1], ['b', new Set([1,2,3])]])}]
let b=[1,'a',{x:[1,2,3], y: new Map([['a',1], ['b', new Set([1,2,3])]])}]

console.log(deepCompare(a,b)) // true

let c=[1,'a',{x:[1,2,3], y: new Map([['a',1], ['b', new Set([1,2,3])]])}]
let d=[1,'a',{x:[1,2,3], y: new Map([['a',1], ['b', 2]])}]

console.log(deepCompare(c, d)) //false

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745548866a4632469.html

相关推荐

  • eloquent - Deep Compare JavaScript function - Stack Overflow

    I'm working my way through the 3rd edition of Eloquent JavaScript and although I've seen one

    13小时前
    40

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信