Sachila Ranawaka
Sachila Ranawaka

Reputation: 41387

compare two arrays of objects

i have two arrays like this. first array is customFields and length is 2

var customFields = [  
   {  
      "$$hashKey":"object:259",
      "fields":[  

      ],
      "id":0.84177744416334,
      "inputType":"number",
      "labelShown":"item",
      "type":"textBox",
      "value":"222222"
   },
   {  
      "$$hashKey":"object:260",
      "fields":[  
         "as",
         "dd",
         "asd"
      ],
      "id":0.51091342118417,
      "inputType":"",
      "labelShown":"labels",
      "type":"selectBox",
      "value":"dd"
   }
]

second one is field and length is 3

var field = [  
   {  
      "fields":[  

      ],
      "id":0.84177744416334,
      "inputType":"number",
      "labelShown":"item",
      "type":"textBox"
   },
   {  
      "fields":[  
         "as",
         "dd",
         "asd"
      ],
      "id":0.51091342118417,
      "inputType":"",
      "labelShown":"labels",
      "type":"selectBox"
   },
   {  
      "fields":[  

      ],
      "id":0.32625015743856,
      "inputType":"text",
      "labelShown":"sample",
      "type":"textBox"
   }
] 

both arrays are dynamic and i need to compare these arrays by id fields and add missing objects to customFields array from field array. how can i do this without 2 for loops looping inside one another. what is the most efficient way. thank you !!!!

Upvotes: 4

Views: 9687

Answers (3)

Joe
Joe

Reputation: 1696

Here's a solution without nested loops. First a lookup table is produced containing ID's of the customFields array. Next the field array is traversed and each missing object is appended to customFields array. Lookup table is also updated to take care of possible duplicates.

var lut = customFields.map(function(obj) {
  return obj.id;
});
field.forEach(function(obj) {
  if (lut.indexOf(obj.id) == -1) {
    customFields.push(obj);
    lut.push(obj.id);
  }
});

As noted in comments, my first proposition hid complexity in indexOf.

Here's an alternative approach that relies on object properties for ID lookup, which is likely better than linear search. lut maintains an association from ID to customFields array index.

var lut = customFields.reduce(function(t, obj, i) {
  t[obj.id] = i;
  return t;
}, {});
field.forEach(function(obj) {
  if (undefined === lut[obj.id]) {
    lut[obj.id] = customFields.push(obj) - 1;
  }
});

Upvotes: 0

Nenad Vracar
Nenad Vracar

Reputation: 122027

You can use reduce() and find() to get desired result.

var customFields = [{"$$hashKey":"object:259","fields":[],"id":0.84177744416334,"inputType":"number","labelShown":"item","type":"textBox","value":"222222"},{"$$hashKey":"object:260","fields":["as","dd","asd"],"id":0.51091342118417,"inputType":"","labelShown":"labels","type":"selectBox","value":"dd"}];
var field = [{"fields":[],"id":0.84177744416334,"inputType":"number","labelShown":"item","type":"textBox"},{"fields":["as","dd","asd"],"id":0.51091342118417,"inputType":"","labelShown":"labels","type":"selectBox"},{"fields":[],"id":0.32625015743856,"inputType":"text","labelShown":"sample","type":"textBox"}]

var result = field.reduce(function(r, e) {
  var f = customFields.find(el => e.id == el.id)
  r.push(f ? f : e)
  return r;
}, [])

console.log(result)

Upvotes: 7

Balaji V
Balaji V

Reputation: 956

You can use native higher order functions such as map and reduce.

Sample implementation using lodash is here. https://github.com/rbs392/object-deep-diff/blob/master/index.js

Upvotes: 1

Related Questions