0

I have a object like below. I can find difference with 'curtain' if i change quantity of it. But in this case it's not working 'sofa' with my function. I want my result will is have all properties of element have property change

obj1 = {
  sofa: [
    {
      name: 'leather',
      typeSofa: [
        {
          name: 'type1',
          text: 'type1',
          quantity: 1
        },
        {
          name: 'type2',
          text: 'type2',
          quantity: 1
        }
      ],
      stool: [
        {
          name: 'type1',
          text: 'type1',
          quantity: 1
        },
        {
          name: 'type2',
          text: 'type2',
          quantity: 1
        }
      ]
    },
    {
      name: 'fabric',
      typeSofa: [
        {
          name: 'type1',
          text: 'type1',
          quantity: 1
        }
      ],
      stool: [
        {
          name: 'type1',
          text: 'type1',
          quantity: 1
        },
        {
          name: 'type2',
          text: 'type2',
          quantity: 1
        }
      ]
    }
  ],
  curtain: {
    dryclean: [{
      name: 'text1',
      text: 'text1',
      quantity; 1
    }];
  }
}

and

obj2 = {
  sofa: [
    {
      name: 'leather',
      typeSofa: [
        {
          name: 'type1',
          text: 'type1',
          quantity: 2
        },
        {
          name: 'type2',
          text: 'type2',
          quantity: 1
        }
      ],
      stool: [
        {
          name: 'type1',
          text: 'type1',
          quantity: 1
        },
        {
          name: 'type2',
          text: 'type2',
          quantity: 1
        }
      ]
    },
    {
      name: 'fabric',
      typeSofa: [
        {
          name: 'type1',
          text: 'type1',
          quantity: 1
        }
      ],
      stool: [
        {
          name: 'type1',
          text: 'type1',
          quantity: 1
        },
        {
          name: 'type2',
          text: 'type2',
          quantity: 1
        }
      ]
    }
  ],
  curtain: {
    dryclean: [
      {
        name: 'text1',
        text: 'text1',
        quantity; 1
      }
    ];
  }
}

In obj2 i just change quantity: 2 How can i have result using js or lodash

result = {
  sofa: [
    {
      name: 'leather',
      typeSofa: [
        {
          name: 'type1',
          text: 'type1'
          quantity: 2
        }
      ]
    }
  ]
}
const findDifferences = (obj1, obj2) => {
    // Find the keys that are in both objects
    const keys = _.intersection(Object.keys(obj1), Object.keys(obj2));

    // Iterate through the keys
    return keys.reduce((diff, key) => {
      const val1 = obj1[key];
      const val2 = obj2[key];

      // If the values are arrays, compare them using _.differenceWith() and recursion
      if (_.isArray(val1) && _.isArray(val2)) {
        diff[key] = _.differenceWith(val2, val1, _.isEqual);
        if (diff[key].length === 0) delete diff[key];
      }
      // If the values are objects, recursively call findDifferences() on them
      else if (_.isObject(val1) && _.isObject(val2)) {
        const nestedDiff = findDifferences(val1, val2);
        if (!_.isEmpty(nestedDiff)) diff[key] = nestedDiff;
      }
      // Otherwise, compare the values directly using _.isEqual()
      else if (!_.isEqual(val1, val2)) {
        diff[key] = val2;
      }

      return diff;
    }, {});
  };

I expected result like this with my function

result = {
  sofa: [
    {
      name: 'leather',
      typeSofa: [
        {
          name: 'type1',
          text: 'type1'
          quantity: 2
        }
      ]
    }
  ]
}
  • You should first explain what you are trying to do, then the problem you are having. It's not clear what you are trying to do here. – Wayne Mar 24 '23 at 22:40
  • Sorry for not being clear, I want the result to be able to return all properties of the element containing the changed property. Like the example above. I want to be able to return name, text and quantity, My function can do that with external properties. But with 'sofa' it's different – Duy Cao Thiện Mar 25 '23 at 06:05

1 Answers1

0

I hope this is what you are looking for. What it does, it compare text and quantity where the name is the same.

const obj1 = {
  sofa: [
    {
      name: "leather",
      typeSofa: [
        {
          name: "type1",
          text: "type1",
          quantity: 1,
        },
        {
          name: "type2",
          text: "type2",
          quantity: 1,
        },
      ],
      stool: [
        {
          name: "type1",
          text: "type1",
          quantity: 1,
        },
        {
          name: "type2",
          text: "type2",
          quantity: 1,
        },
      ],
    },
    {
      name: "fabric",
      typeSofa: [
        {
          name: "type1",
          text: "type1",
          quantity: 1,
        },
      ],
      stool: [
        {
          name: "type1",
          text: "type1",
          quantity: 1,
        },
        {
          name: "type2",
          text: "type2",
          quantity: 1,
        },
      ],
    },
  ],
  curtain: {
    dryclean: [
      {
        name: "text1",
        text: "text1",
        quantity: 1,
      },
    ],
  },
};

const obj2 = {
  sofa: [
    {
      name: "leather",
      typeSofa: [
        {
          name: "type1",
          text: "type1",
          quantity: 2,
        },
        {
          name: "type2",
          text: "type2",
          quantity: 1,
        },
      ],
      stool: [
        {
          name: "type1",
          text: "type1",
          quantity: 1,
        },
        {
          name: "type2",
          text: "type2",
          quantity: 1,
        },
      ],
    },
    {
      name: "fabric",
      typeSofa: [
        {
          name: "type1",
          text: "type1",
          quantity: 1,
        },
      ],
      stool: [
        {
          name: "type1",
          text: "type1",
          quantity: 1,
        },
        {
          name: "type2",
          text: "type2",
          quantity: 1,
        },
      ],
    },
  ],
  curtain: {
    dryclean: [
      {
        name: "text1",
        text: "text1",
        quantity: 1,
      },
    ],
  },
};

const result = { sofa: [] };

_.forEach(obj1.sofa, (sofa, i) => {
  _.forEach(sofa.typeSofa, (typeSofa, j) => {
    const obj2TypeSofa = _.find(obj2.sofa[i].typeSofa, { name: typeSofa.name });
    if (obj2TypeSofa && !_.isEqual(typeSofa, obj2TypeSofa)) {
      result.sofa.push({
        name: sofa.name,
        typeSofa: [
          {
            name: obj2TypeSofa.name,
            text: obj2TypeSofa.text,
            quantity: obj2TypeSofa.quantity,
          },
        ],
      });
    }
  });
});

console.log(result);



/*

// In case you also want to look for difference at curtain object you will have to add this lines of code.

 // Change result to this
const result = { sofa: [], curtain: { dryclean: [] } };

// Add these lines below
_.forEach(obj1.curtain.dryclean, (curtain, i) => {
  const obj2Curtain = _.find(obj2.curtain.dryclean, { name: curtain.name });
  if (obj2Curtain && (!_.isEqual(curtain, obj2Curtain))) {
    result.curtain.dryclean.push({
      name: obj2Curtain.name,
      text: obj2Curtain.text,
      quantity: obj2Curtain.quantity
    });
  }
});

*/
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
ChahinDev
  • 36
  • 5