Deep equal in any order

Any plans to support the deep-equal-in-any-order chai plugin in test scripts?
https://www.chaijs.com/plugins/deep-equal-in-any-order/

… if not, is there an alternative? I tried loading the plugin dynamically, via environment variable, but couldn’t seem to make it work.

1 Like

I agree this is needed in Postman. Is there any plan to integrate?

lodash is included in the postman sandbox. You could do one of two things:

  1. Sort both arrays and use isEqual
pm.expect(_.isEqual(_.sortBy(arr1), _.sortBy(arr2))).to.be.true;
  1. Use xor from lodash
pm.expect(_.xor(arr1, arr2).length).to.equal(0);

Stack Overflow reference

@allen.helton
Hello

If the array contains objects the sorting does not work fine. Unfortunatly I tried your suggestion before but does not work for nested objects.

What about using xor?

@allen.helton
Hello,
Thank you for your help. Unfortunately doesn’t work neither

json1 = {
  "a": 1,
  "b": {"toto" : "toto",
    "array" : [
    {"old": {
      "value" :1
    }},
    {"new": {
      "value" :2
    }}
  ]
}
}


json2 = {
  "a": 1,
  "b": {"toto" : "toto",
    "array" : [
   {"new": {
      "value" :2
    }},
     {"old": {
      "value" :1
    }}
  ]
}
}

json3 = {
    "b": {"toto" : "toto",
    "array" : [
    {"old": {
      "value" :1
    }},
    {"new": {
      "value" :2,
      "other" : 4
    }}
  ]
},
  "a": 1

}

function customizer(baseValue, value) {
    
      if (Array.isArray(baseValue) && Array.isArray(value)) {
              return lodash.isEqual(lodash.sortBy(baseValue), lodash.sortBy(value))
            }
        
      }


console.log(lodash.isEqualWith(json1,json2,customizer)) -> false (I expected true as only array order changes)
console.log(lodash.isEqual((lodash.sortBy(json1),lodash.sortBy(json2)))) -> same as above
console.log(lodash.xor(json1, json2).length)  -> 0
console.log(lodash.xor(json1, json3).length)  -> 0  (I expected different than 0 because of "other" in json3)

Thank you for your assistance. Any idea?

Best regards

PS : I have tried as well the isMatch however it’s too permissive. I need to have same length in arrays (even nested ones), and I need to have same fields in both json (isMatch only does a partial deep comparison so doesn’t work neither)

At this point the only thing I can think of is to loop through the arrays, try to find a match, and use _.isEqual on the match.

Not the best solution, but might work.

@allen.helton Hello thank you for your suggestion.
I figured out a way that works for me. I post it here in case someone looking for the same.

function customizer(objValue, srcValue, key, object, source) {
     
   if(Object.keys(object).length !== Object.keys(source).length){
     return false;
   }

  if(typeof objValue ==='object' && typeof srcValue === 'object'){
        if(Object.keys(objValue).length !== Object.keys(srcValue).length ){
                    return false;
        }
      }
      if (Array.isArray(objValue) && Array.isArray(srcValue)) {
           if(!(objValue.length === srcValue.length)){
              return false;
            }
        
      }
  }

console.log(lodash.isMatchWith(json1,json2,customizer))
1 Like

Nice work! That should do it :slight_smile:

1 Like

Hello

This works well to identify if two json are the same disregarding order. However I didn’t figure out a way to print the diff :confused:

So for me solves half of my problem.

You could iterate over the keys of one object, see if there is a matching key/value in the other one, and if no match, you could print it out.

Then you would iterate over the other object and do the same thing.

Again, it’s not elegant and is a decent amount of code, but seems like you know your way around javascript.

Hello

This doesn’t work well for example if you have an item in source that is not present in the other json. I created an issue for this: https://github.com/lodash/lodash/issues/4900