0

I have two Objects with this structure:

Obj1:

{
 0: {name:"", id: 0},
 1: {"age": "", id:0},
 2: {name:"", id: 1},
 3: {"age": "", id:1},
}

I do a trigger to one of the properties and I end up with the following:

Obj2:

{
 0: {name:"", id: 0},
 1: {"age": "", id:0},
 2: {name:"john", id: 1},
 3: {"age": "", id:1},
}

I need to create a function to basically loop trough the 2 objects, see if there are changes and return those changes, in this case the return would have something like [{name:"john", id:1}]

I've search for some answers but I can only find loops through flat objects

I also tried to start the function but I keep getting stuck because I don't know how loop through obj2 at the same time

function objDiff(object1, object2){
   for(var set in object1) {
      for(property in set) {
        // Do the comparison
      }
   } 
}

The ids don't really change, only the first property.

I need some insights on how I can start looping trough both at the same time

user9875
  • 133
  • 1
  • 4

2 Answers2

0

I don't know how efficient this will be for your objects but you can loop through the elements of the second object's values and stringfy them and then filter the noes that are not part of the stringfied first object:

let obj1 = {
 0: {name:"", id: 0},
 1: {"age": "", id:0},
 2: {name:"", id: 1},
 3: {"age": "", id:1},
}

let obj2 = {
 0: {name:"", id: 0},
 1: {"age": "", id:0},
 2: {name:"john", id: 1},
 3: {"age": "", id:1},
}
let obj1String = JSON.stringify(obj1);
let result = Object.values(obj2).filter((e) => !obj1String.includes(JSON.stringify(e)))
console.log(result);
Alan Omar
  • 4,023
  • 1
  • 9
  • 20
0

I'm going to suggest you rewrite your code to give you a better data structure to work with. I know this might not be the most popular answer, and it's definitely not the easiest thing to do, nor will it likely be well received by anyone else working with your codebase, but it'll likely help you in the long run.

Instead of having this:

obj1 = {
 0: {name:"", id: 0},
 1: {"age": "", id:0},
 2: {name:"", id: 1},
 3: {"age": "", id:1}
};

You should have this:

obj1 = [
 {name:"", "age": "", id: 0},
 {name:"", "age": "", id: 1},
 ...
];

This becomes an array of objects, where there's a single object for each "person", or whatever you're trying to deal with. Then when you get new data, you can just search for the id and update whatever's necessary.

Having 2 different objects in the same array isn't a good idea and leads to this kind of problem where you don't know what object you're dealing with in each array element. Your code compounds this with instead of it being an array, it's an object pretending to be an array, which is harder to deal with. You might have to turn your key list into an array to loop over everything, which isn't efficient.

let obj1 = {
 0: {name:"", id: 0},
 1: {"age": "", id:0},
 2: {name:"", id: 1},
 3: {"age": "", id:1}
};

let keys = Object.keys(obj1);

for (let i = 0; i < keys.length; i++){
  console.log(obj1[i]);
}

Having it as an array avoids the extra steps to pull out the keys from the object. For a small app, this might not be such a big issue, but if it's a game or stock market app where timing is fairly critical and this is being done multiple times a second or in a loop, it adds up quickly. As an array, it's simpler and faster, and you can add more elements easily and in an expected way.

Leaving it with multiple objects in a single array will mean that you have to test for what type of object it is for every single element, spending time you might not want to spend.

let obj1 = [
 {name:"", id: 0},
 {"age": "", id:0},
 {name:"", id: 1},
 {"age": "", id:1}
];

for (let i = 0; i < obj1.length; i++){
  console.log(obj1[i]);
}

As an FYI, you shouldn't mix your property declarations like you are. Use quotes around all property names or don't use it on any. {name:"", "age": "", id: 0} becomes {name:"", age: "", id: 0} or {"name":"", "age": "", "id": 0}. Browsers generally don't care, but sometimes they do and when they do, it'll mess with you badly, giving you weird errors that are hard to track down.

You also don't need to make sure that the ids are in the "correct" order, either, when your data is in an array. So converting it to a single object in an array, this should simplify your code considerably and make it much easier to expand later, becoming:

let obj1 = [
 {name: "", age: "", id: 0},
 {name: "", age: "", id: 1}
];

let obj2 = [
 {name: "john", age: "", id: 1},
 {name: "jacob", age: "", id: 0}
];

for (let i = 0; i < obj1.length; i++){
  console.log(obj1[i]);

  for (let j = 0; j < obj2.length; j++){
    console.log(obj2[j]);

    if (obj1[i].id === obj2[j].id)
    {
      obj1[i].age = obj2[j].age;
      obj1[i].name = obj2[j].name;
      break;
    }
  }
}

Even if you get the data from an API in the way you lay it out initially, you can still convert it to the better format within your JavaScript, then, if/when you need to send the data back to the API, convert it back before you send it. This complicates the process of sending data, but should simplify everything else in your client side app.

computercarguy
  • 2,173
  • 1
  • 13
  • 27