0

This is my object

   let products = [
      { "productName": "A", "storage": "Lot 1", "quantity": 1000, "status": "stockIn" },
      { "productName": "A", "storage": "Lot 1", "quantity": 100, "status": "stockIn"  },
      { "productName": "A", "storage": "Lot 1", "quantity": 500, "status": "stockOut" },
      { "productName": "A", "storage": "Lot 2", "quantity": 500, "status": "stockIn"  }
   ]

This is what I am trying to achieve

   let result = [
      { "productName": "A", "storage": "Lot 1", "stockIn": 1100, "stockOut": 500, "available":600 },
      { "productName": "A", "storage": "Lot 2", "stockIn": 500, "stockOut": 0, "available":500   }
   ]

Please kindly provide an idea on how to achieve this without redundant codes. Thanks

var storage = new Set(products.map(item => item.storage));

storage.forEach(lot => {

var stockIn = products.filter(item => item.storage === storage && item.status == 'stockIn')
    .map(({ storage, quantity }) => ({ storage, quantity }));

var stockInSum = stockIn.reduce((prev, curr, index) => prev + curr.quantity, 0);

var stockOut = products.filter(item => item.storage === storage && item.status == 'stockOut')
    .map(({ storage, quantity }) => ({ storage, quantity }))

var stockOutSum = stockOut.reduce((prev, curr, index) => prev + curr.quantity, 0);

}
2
  • What have you tried so far to solve this on your own? Commented Feb 26, 2022 at 12:43
  • @Andreas I have updated my code. I tried that. Commented Feb 26, 2022 at 12:55

2 Answers 2

1
  • Using Array#reduce, iterate over the array while updating a Map where the key is the combination of productName and storage, and the value is the corresponding grouped object
  • In every iteration, using the current key, get the pair if exist and deconstruct stockIn and stockOut. According to the current status, update one of the latter values and compute available. Finally, using Map#set, create/update the pair.
  • Using Map#values, get the list of grouped objects

const products = [
  { productName: "A", storage: "Lot 1", quantity: 1000, status: "stockIn" },
  { productName: "A", storage: "Lot 1", quantity: 100,  status: "stockIn"  },
  { productName: "A", storage: "Lot 1", quantity: 500,  status: "stockOut" },
  { productName: "A", storage: "Lot 2", quantity: 500,  status: "stockIn"  }
];

const result = [...
  products.reduce((map, { productName, storage, quantity, status }) => {
    const key = `${productName}-${storage}`;
    let { stockIn = 0, stockOut = 0 } = map.get(key) ?? {};
    if(status === 'stockIn') stockIn += quantity;
    else stockOut += quantity;
    const available = stockIn - stockOut;
    map.set(key, { productName, storage, stockIn, stockOut, available });
    return map;
  }, new Map)
  .values()
];

console.log(result);

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

1 Comment

Brilliant. Works like a charm. You are the man. .Thanks bro.
0

Here is the general pattern. I will leave it to you to figure out the other fields.

const reduced = products.reduce( (a,v) => {
  const found = a.find(it=>it.lot === v.lot && it.productName === v.productName)
  if (found) {
    a.quantity += v.quantity
    // aggregate your other fields here.
  }
  else {
    a.push(v)
  }
  return a
}, [] )

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.