Reputation: 41387
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
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
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
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