Search code examples
javascriptarrayscomparelodash

Comparing objects with nested arrays of objects disregarding the order


I have two objects, for example:

const objA = {
  any: 'string',
  some: {
    prop: [
      {a: 1, b: 2},
      {a: 3, b: 4}
    ],
  }
};

const objB = {
  some: {
    prop: [
      {a: 3, b: 4},
      {a: 1, b: 2}
    ],
  },
  any: 'string'
};

I'd like to have a comparing method them so that the result in this case would be that these objects are equal. So, it needs to be a deep comparison and if an array occurs, the method would compare the objects inside this array, disregarding the order of objects in the array.

I tried to use the lodash isEqual function but it checks the array elements order as well. What would be the best solution?


Solution

  • You could turn the objects into strings and sort objects properties by key, and arrays by their contents strings.

    const objHash = obj => {
      if(typeof obj !== "object" || obj === null)
       return JSON.stringify(obj);
       
      if(Array.isArray(obj))
        return "[" + obj.map(objHash).sort().join(",") + "]";
        
      return "{" + Object.entries(obj).sort(([kA], [kB]) => kA.localeCompare(kB)).map(([k, v]) => k + ":" + objHash(v)).join(",") + "}";
    }
        
    
    const objA = {
      some: {
        prop: [
          {a: 1, b: 2},
          {a: 3, b: 4}
        ],
      },
      any: 'string'
    };
    
    const objB = {
      some: {
        prop: [
          {a: 3, b: 4},
          {a: 1, b: 2}
        ],
      },
      any: 'string'
    };
    
    console.log("objA: ", objHash(objA));
    console.log("objB: ", objHash(objB));