In my code, I have used two forEach loops. But in order to optimize my code, I have been instructed not to use forEach loop inside a forEach loop. So I don't want to loop over the second array obj3. I just want to get the values at a certain position without using the inner forEach loop. Here is my code : -
var obj2 = [{
"name": "4134",
"calls": [
]
}]
var obj3 = [{ Channel: 'SIP/4134-0004462a',
State: 'Up',
Accountcode: '7013658596'},
{ Channel: 'SIP/4334-sa',
State: 'Up',
Accountcode: '07717754702',
}]
var function = (obj2, obj3) => {
obj2.forEach((a) =>
obj3.forEach((b) => {
if (b.Channel.includes(a.name)) a.calls = (a.calls || []).concat(Object.assign({}, { MobileNo: b.Accountcode, Status : b.State}));
})
);
};
function(obj2, obj3);
The above code loops through obj2 and obj3 and if the value of the name key exist in the Channel key's value then it picks the Accountcode and State from obj3 and pushes them in the calls array of the obj2. Here is the output array:-
[ {
"name": "4134",
"calls": [
{
"MobileNo": "7013658596",
"Status": "Up"
}
]
}]
What I have done so far
var func = (obj2, obj3) => {
var channelArr = [];
const Channels = obj3.reduce((acc, curVal) => {
obj2.forEach((item)=>{
if(curVal.Channel.includes(item.name)){
item.calls.push({'MobileNo':curVal.Accountcode,'Status': curVal.State})
}
})
return obj2;
}, [])
};
I tried doing it using reduce function but I'm really not sure if this can improve the performance. Please do let me know if you have better suggestions.
Since the names are in a predictable location inside Channel, you can build an object indexed by names from the obj3 initially, and then just use bracket notation to get the array you need, O(n):
var obj2 = [{
"name": "4134",
"calls": [
]
}];
var obj3 = [{
Channel: 'SIP/4134-0004462a',
State: 'Up',
Accountcode: '7013658596'
},
{
Channel: 'SIP/4334-sa',
State: 'Up',
Accountcode: '07717754702',
}
]
const objsByName = obj3.reduce((a, item) => {
const { Channel } = item;
const name = Channel.match(/\/(\d+)/)[1];
if (!a[name]) a[name] = [];
a[name].push(item);
return a;
}, {});
obj2.forEach(({ name, calls }) => {
calls.push(...objsByName[name]);
});
console.log(obj2);
I tried using filter and map, check it out if this works for you.
const result = obj2.map(a => {
const foundAll = obj3.filter(
({ Channel, Accountcode, State }) =>
Channel.includes(a.name) && { Accountcode, State }
);
return {
name: a.name,
calls: [...a.calls, foundAll]
};
});
console.info(result);
Find working Bin here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With