Patrick
Patrick

Reputation: 4298

Update an array of objects with a different array of objects data

I have a very tricky manipulation to do. So here it is.

I have an array of Objects named 'data1'

[Object, Object, Object]
       0:Object
               id="00456145"     //check this 
               name: "Rick"
               upper:"0.67"
               lower:"-0.34"
      1:Object
               id="00379321"     
               name:"Anjie"
               upper:"0.46"
               lower:"-0.56"
      2:Object
               id="00323113"      
               name:"dillan"
               upper:"0.23"
               lower:"-0.11"

I am only interested in id, upper and lower values from these array of objects.

Here is the second array of objects named 'data2'

[Object, Object]
     0:Object
             id="0045614"   //present here if we remove last element of '00456145'
             cast="Rick"
             Contact: "Yes"
             upper:"0.11"    //need to be updated to '0.67'
             lower:"-0.11"   //need to be updated to '-0.34'
     1:Object
             id="0032311"     //present here if we remove last element of '00323113'
             cast:"dillan"
             Contact:"Maybe"
             upper:"0.11"
             lower:"-0.11"

So, this is what i have to do. I will first check 'data1'. id present in 'data1' is checked. For e.g. object 0 has id="00456145"

I remove the last number present in it. so it becomes id="0045614". Then i compare if this id is present in the object 'data2'.

If it is present, the upper and lower values present for that object 0 in 'data1' is passed to object 'data2' where the id is present. In this case object 0 of 'data2' has the id= '0045614'.

So upper and lower values will be updated to 0.67 and -0.34 respectively.

Similarly for other arrays. So the final output should look like this of 'data2'

[Object, Object]
     0:Object
             id="0045614"   
             cast="Rick"
             Contact: "Yes"
             upper:"0.67"    //updated
             lower:"-0.34"   //updated
     1:Object
             id="0032311"  
             cast:"dillan"
             Contact:"Maybe"
             upper:"0.23"      //updated
             lower:"-0.11"     //updated

Upvotes: 0

Views: 78

Answers (6)

Nina Scholz
Nina Scholz

Reputation: 386680

I suggest to use either an object as hash table or a map. Then only two loops are necessary, one for getting the references and one for the assignments.

Big O: O(n + m)

While I actually not know which one (Map vs Object) is more suited, you may get your own picture:

Proposal with Object

var data1 = [{ id: "00456145", name: "Rick", upper: "0.67", lower: "-0.34", }, { id: "00379321", name: "Anjie", upper: "0.46", lower: "-0.56", }, { id: "00323113", name: "dillan", upper: "0.23", lower: "-0.11" }],
    data2 = [{ id: "0045614", cast: "Rick", Contact: "Yes", upper: "0.11", lower: "-0.11", }, { id: "0032311", cast: "dillan", Contact: "Maybe", upper: "0.11", lower: "-0.11" }],
    hash = Object.create(null);

data1.forEach(function (a) {
    hash[a.id.slice(0, -1)] = a;
});

data2.forEach(function (a) {
    var o = hash[a.id];
    o && Object.keys(o).forEach(function (k) {
        if (k !== 'id' && a[k] !== o[k]) {
            a[k] = o[k];
        }
    });
});

console.log(data2);

Proposal with Map

var data1 = [{ id: "00456145", name: "Rick", upper: "0.67", lower: "-0.34", }, { id: "00379321", name: "Anjie", upper: "0.46", lower: "-0.56", }, { id: "00323113", name: "dillan", upper: "0.23", lower: "-0.11" }],
    data2 = [{ id: "0045614", cast: "Rick", Contact: "Yes", upper: "0.11", lower: "-0.11", }, { id: "0032311", cast: "dillan", Contact: "Maybe", upper: "0.11", lower: "-0.11" }],
    map = new Map;

data1.forEach(function (a) {
    map.set(a.id.slice(0, -1), a);
});

data2.forEach(function (a) {
    var o = map.get(a.id);
    o && Object.keys(o).forEach(function (k) {
        if (k !== 'id' && a[k] !== o[k]) {
            a[k] = o[k];
        }
    });
});

console.log(data2);

Upvotes: 2

KevBot
KevBot

Reputation: 18908

I like array#some in this case, so that you can get out of the loop so there are no unnecessary iterations:

var data1 = [{ id: "00456145", name: "Rick", upper: "0.67", lower: "-0.34" }, { id: "00379321", name: "Anjie", upper: "0.46", lower: "-0.56" }, { id: "00323113", name: "dillan", upper: "0.23", lower: "-0.11" }];
var data2 = [{ id: "0045614", cast: "Rick", Contact: "Yes", upper: "0.11", lower: "-0.11" }, { id: "0032311", cast: "dillan", Contact: "Maybe", upper: "0.11", lower: "-0.11" }];

data2 = data2.map(function(item) {
  data1.some(function(a) {
    if (item.id == a.id.slice(0, -1)) {
      item.upper = a.upper;
      item.lower = a.lower;
      return true;
    }
  });

  return item;
});

console.log(data2);

Upvotes: 2

Zohaib Ijaz
Zohaib Ijaz

Reputation: 22895

Here is a solution using Array.prototype.forEach. Loop through data2 objects and if id matches with any object in data1, update values with matching one.

var data1 = [{
    id: "00456145",
    name: "Rick",
    upper: "0.67",
    lower: "-0.34"
  }, {
    id: "00379321",
    name: "Anjie",
    upper: "0.46",
    lower: "-0.56"
  }, {
    id: "00323113",
    name: "dillan",
    upper: "0.23",
    lower: "-0.11"
  }];

  var data2 = [{
    id: "0045610", //present here if we remove last element of '00456145'
    cast: "Rick",
    Contact: "Yes",
    upper: "0.11", //need to be updated to '0.67'
    lower: "-0.11" //need to be updated to '-0.34'
  }, {
    id: "0032311", //present here if we remove last element of '00323113'
    cast: "dillan",
    Contact: "Maybe",
    upper: "0.11",
    lower: "-0.11"
  }];

data2.forEach(function(item2){
   data1.forEach(function(item1){
   if (item1.id.substring(0,7) === item2.id){ // can be `item1.id.indexOf(item2.id) == 0
     item2.upper = item1.upper;
     item2.lower = item1.lower;
   }
  });
});

console.log(data2);

Upvotes: 1

Philip
Philip

Reputation: 3536

Maybe this is what you want.

var data1 = [{
  id: "00456145",
  name: "Rick",
  upper: "0.67",
  lower: "-0.34"
}, {
  id: "00379321",
  name: "Anjie",
  upper: "0.46",
  lower: "-0.56"
}, {
  id: "00323113",
  name: "dillan",
  upper: "0.23",
  lower: "-0.11"
}];

var data2 = [{
  id:"0045614",
  cast:"Rick",
  Contact: "Yes",
  upper:"0.11",
  lower:"-0.11",
}, {
  id:"0032311",
  cast:"dillan",
  Contact:"Maybe",
  upper:"0.11",
  lower:"-0.11",
}];


data2.forEach(function(data2Value) {
  data1.forEach(function(data1Value) {
    if(data1Value.id.substr(0, data1Value.id.length - 1) === data2Value.id) {
      data2Value.upper = data1Value.upper;
      data2Value.lower = data1Value.lower;
    }
  });
});

console.log(data2);

Upvotes: 1

Hector Barbossa
Hector Barbossa

Reputation: 5528

You can use something like

  data1.forEach(function(obj) {
      var search = obj.id.slice(0, -1);
      data2.forEach(function(d) {
          if (d.id === search) {
              d.upper = obj.upper;
              d.lower = obj.lower;
          };
      });
  });

to do this.

Upvotes: 1

Doron Brikman
Doron Brikman

Reputation: 2584

You can try something like that:

for (var i = 0; i < data1.length; i++) {
  var item = data1[i];
  var trim = item.id.substr(0, item.id.length - 1);
  for (var j = 0; j < data2.length; j++) {
    var item2 = data2[j];
    if (item2.id === trim) {
      item2.upper = item.upper;
      item2.lower = item.lower;
    }
  }
}

and if you are using es6 you can simplify the code by:

for (let item of data1) {
  let trim = item.id.substr(0, item.id.length - 1);
  for (let item2 of data2) {
    if (item2.id === trim) {
      item2.upper = item.upper;
      item2.lower = item.lower;
    }
  }
}

Upvotes: 1

Related Questions