0

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
Patrick
  • 3,938
  • 6
  • 20
  • 32

6 Answers6

2

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);
KevBot
  • 17,900
  • 5
  • 50
  • 68
2

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);
Community
  • 1
  • 1
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
1

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;
    }
  }
}
Doron Brikman
  • 2,444
  • 1
  • 16
  • 17
1

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);
Zohaib Ijaz
  • 21,926
  • 7
  • 38
  • 60
  • does this work ? function(item2) and function(item1). a bit confused about wat are those referring to – Patrick Jun 30 '16 at 23:01
  • 1
    forEach loop will iterate over the items/objects of array. So with each iteration, an object from array is passed to anonymous callback function. item2 is an object from data2 array and item1 is an object from daat1. – Zohaib Ijaz Jun 30 '16 at 23:07
1

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.

Hector Barbossa
  • 5,506
  • 13
  • 48
  • 70
  • hecotr, wat are obj and d in the function() you mentioned. – Patrick Jun 30 '16 at 23:02
  • 1
    These are the individual objects of your array. obj will give the object at index 0, 1 , 2 respectively in each iteration of the forEach loop. Similarly, d gives you acces to individual objects of array data2. – Hector Barbossa Jun 30 '16 at 23:05
1

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);
Philip
  • 3,486
  • 1
  • 24
  • 37