2

I need to replace elements in array by elements from another array by orderID key of the object. If the element is not in the array then it should be added.

I have implemented it (the example in code snippet below) and it mostly works.

The problem is that my implementation uses filter inside loop and it can be performance issue for large data.

Can it be implemented without loop inside loop?

let storageOrders = [
  {orderID:1, data:'data1'},
  {orderID:2, data:'data2'},
  {orderID:3, data:'data3'},
  {orderID:4, data:'data4'},
];
let summaryOrders = [
  {orderID:2, data:'data2_new'},
  {orderID:3, data:'data3_new'},
  {orderID:5, data:'data5'},
];
summaryOrders.forEach((order) => {
  storageOrders = storageOrders.filter(storageOrder => storageOrder.orderID !== order.orderID);
  storageOrders.push(order);
});
console.log(storageOrders);

1
  • 1
    @Dznitry You may try sorting both arrays. Even for large arrays its only nLog n vs. n^2 which you perform now. After sorting, go over summaryOrders and check for the next element in storageOrders. Simple. The total operations will be: 2nlog(n)+n. Assuming arrays are of similar size. If not, I leave you to do the math... :-) Commented Sep 27, 2019 at 16:05

2 Answers 2

3

You can create a mapping from orderID to object using both storageOrders and summaryOrders (one after the other so that values from summaryOrders take precedence for ids that are already there). Then you can recreate your final array with Object.values:

let storageOrders = [
  {orderID:1, data:'data1'},
  {orderID:2, data:'data2'},
  {orderID:3, data:'data3'},
  {orderID:4, data:'data4'},
];
let summaryOrders = [
  {orderID:2, data:'data2_new'},
  {orderID:3, data:'data3_new'},
  {orderID:5, data:'data5'},
];

storageOrders = Object.values([...storageOrders, ...summaryOrders].reduce((a, c) => {
  a[c.orderID] = c;
  return a;
}, {}));
console.log(storageOrders);

Sign up to request clarification or add additional context in comments.

Comments

1

You could create an object from the existing orders and then loop through the new / updated orders to update your existing order object. This could be a better way to store your data altogether, but, if needed, you could convert the updated object back to a list of objects.

const mergeOrders = (a, b) => {
  const obj = a.reduce((acc, order) => {
    acc[order.orderID] = order.data;
    return acc;
  }, {});
  
  for (const order of b) {
    obj[order.orderID] = order.data;
  }
  
  return Object.entries(obj).map(([id, data]) => ({ orderID: id, data: data }));
};

const storageOrders = [{ orderID: 1, data: 'data1' }, { orderID: 2, data: 'data2' }, { orderID: 3, data: 'data3' }, { orderID: 4, data: 'data4' }];
const summaryOrders = [{ orderID: 2, data: 'data2_new' }, { orderID: 3, data: 'data3_new' }, { orderID: 5, data: 'data5' }];
const orders = mergeOrders(storageOrders, summaryOrders);
console.log(orders);
// [{ orderID: 1, data: 'data1' }, { orderID: 2, data: 'data2_new' }, { orderID: 3, data: 'data3_new' }, { orderID: 4, data: 'data4' }, { orderID: 5, data: 'data5' }]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.