Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

remove nested foreach loops

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.

like image 787
node_man Avatar asked May 18 '26 17:05

node_man


2 Answers

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);
like image 137
CertainPerformance Avatar answered May 20 '26 06:05

CertainPerformance


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.

like image 45
Hardik Pithva Avatar answered May 20 '26 07:05

Hardik Pithva



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!