2

In my input array of object, I have a field called Grade. This is the filtering parameter

var input = [
 {
  "Qty": "2.00",
  "Grade": "AU27",
  "Thickness": "5.00",
  "Width": "1200.00",
 },
 {
  "Qty": "7.00",
  "Grade": "AU27",
  "Thickness": "10.00",
  "Width": "1400.00",
 },
 {
  "Qty": "17.00",
  "Grade": "AU27",
  "Thickness": "5.00",
  "Width": "1700.00",
 },
 {
  "Qty": "51.00",
  "Grade": "FE500D",
  "Thickness": "10.00",
  "Width": "1100.00",
 },
 {
  "Qty": "69.00",
  "Grade": "FE500D",
  "Thickness": "12.00",
  "Width": "1500.00",
 },
 {
  "Qty": "30.00",
  "Grade": "FE500D",
  "Thickness": "8.00",
  "Width": "1800.00",
 },
 {
  "Qty": "92.00",
  "Grade": "FE500D",
  "Thickness": "10.00",
  "Width": "2200.00",
 },
 {
  "Qty": "98.00",
  "Grade": "FE600D",
  "Thickness": "11.00",
  "Width": "2400.00",
 },
 {
  "Qty": "115.00",
  "Grade": "FE600D",
  "Thickness": "17.00",
  "Width": "2600.00",
 }
];

I want to create array of object called sumGradeArray from the above input array. If we consider the total quantities of different grades, irrespective of thickness and width, then total quantity of Grade AU27 is 2.00 + 7.00 + 17.00 = 26.00.

Similarly for grade FE500D total quantity is 51.00 + 69.00 + 30.00 + 92.00 = 242.00

Similarly for grade FE600D total quantity is 98.00 + 115.00 = 213.00

 var sumGradeArray = [
 {      
  "Grade": "AU27",
  "TotalQty": "26.00",
 },
 {      
  "Grade": "FE500D",
  "TotalQty": "242.00",
 },
 {      
  "Grade": "FE600D",
  "TotalQty": "213.00",
 },
];

Please someone provide me a generic solution using Vanilla JS(no Jquery/Lodash). I am showing just 3 grades here, in reality the input array of object is an API response. It can have hundreds of grades

1
  • 1
    You don't get the show....what have you tried so far Commented Apr 21, 2019 at 17:45

3 Answers 3

1

You could take a Map for grouping same grade and render the wanted style.

var input = [{ Qty: "2.00", Grade: "AU27", Thickness: "5.00", Width: "1200.00" }, { Qty: "7.00", Grade: "AU27", Thickness: "10.00", Width: "1400.00" }, { Qty: "17.00", Grade: "AU27", Thickness: "5.00", Width: "1700.00" }, { Qty: "51.00", Grade: "FE500D", Thickness: "10.00", Width: "1100.00" }, { Qty: "69.00", Grade: "FE500D", Thickness: "12.00", Width: "1500.00" }, { Qty: "30.00", Grade: "FE500D", Thickness: "8.00", Width: "1800.00" }, { Qty: "92.00", Grade: "FE500D", Thickness: "10.00", Width: "2200.00" }, { Qty: "98.00", Grade: "FE600D", Thickness: "11.00", Width: "2400.00" }, { Qty: "115.00", Grade: "FE600D", Thickness: "17.00", Width: "2600.00" }],
    result = Array.from(
        input.reduce((m, o) => m.set(o.Grade, (+(m.get(o.Grade) || 0) + +o.Qty).toFixed(2)), new Map),
        ([Grade, TotalQty]) => ({ Grade, TotalQty })
    );

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

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

4 Comments

@window.document, right. thank you for the hint. please see edit.
@Nina Scholz Your answer is not correct. I am not getting the desired array of object. The sum is totally incorrect. Maheer Ali's answer is correct (except that he probably missed to show the results in 2 decimal places)
@RobbieCrusoe, please reload the page and check the result.
@Nina Scholz Thanks your new solution works. I accept your answer
1

You can use reduce() and findIndex() for this.

var input = [ { "Qty": "2.00", "Grade": "AU27", "Thickness": "5.00", "Width": "1200.00", }, { "Qty": "7.00", "Grade": "AU27", "Thickness": "10.00", "Width": "1400.00", }, { "Qty": "17.00", "Grade": "AU27", "Thickness": "5.00", "Width": "1700.00", }, { "Qty": "51.00", "Grade": "FE500D", "Thickness": "10.00", "Width": "1100.00", }, { "Qty": "69.00", "Grade": "FE500D", "Thickness": "12.00", "Width": "1500.00", }, { "Qty": "30.00", "Grade": "FE500D", "Thickness": "8.00", "Width": "1800.00", }, { "Qty": "92.00", "Grade": "FE500D", "Thickness": "10.00", "Width": "2200.00", }, { "Qty": "98.00", "Grade": "FE600D", "Thickness": "11.00", "Width": "2400.00", }, { "Qty": "115.00", "Grade": "FE600D", "Thickness": "17.00", "Width": "2600.00", } ];

const res = input.reduce((ac,{Grade,Qty}) => {
  let index = ac.findIndex(x => x.Grade === Grade);
  index === -1 ? ac.push({Grade,totalQty:+Qty}) : ac[index].totalQty += +Qty
  return ac;
},[]).map(x => ({...x,totalQty:x.totalQty.toFixed(2)}))
console.log(res)

3 Comments

Please want the answer in 2 decimal places
I upvoted you too. But since Nina Scholz answered first, I marked her as correct.
I clicked on the upvote but yes possibly they are not allowing me to upvote.
1

Why do you want your quantities represented as strings in the end result when they are in fact numbers? And why not structure your object as { [grade]: <quantity> } as your object is now unique on grade and this will be easier to access and operate on?

My answer assumes you agree to do those two things

Code Snippet

var input = [
 {
  "Qty": "2.00",
  "Grade": "AU27",
  "Thickness": "5.00",
  "Width": "1200.00",
 },
 {
  "Qty": "7.00",
  "Grade": "AU27",
  "Thickness": "10.00",
  "Width": "1400.00",
 },
 {
  "Qty": "17.00",
  "Grade": "AU27",
  "Thickness": "5.00",
  "Width": "1700.00",
 },
 {
  "Qty": "51.00",
  "Grade": "FE500D",
  "Thickness": "10.00",
  "Width": "1100.00",
 },
 {
  "Qty": "69.00",
  "Grade": "FE500D",
  "Thickness": "12.00",
  "Width": "1500.00",
 },
 {
  "Qty": "30.00",
  "Grade": "FE500D",
  "Thickness": "8.00",
  "Width": "1800.00",
 },
 {
  "Qty": "92.00",
  "Grade": "FE500D",
  "Thickness": "10.00",
  "Width": "2200.00",
 },
 {
  "Qty": "98.00",
  "Grade": "FE600D",
  "Thickness": "11.00",
  "Width": "2400.00",
 },
 {
  "Qty": "115.00",
  "Grade": "FE600D",
  "Thickness": "17.00",
  "Width": "2600.00",
 }
];

const sumGradeArray = input.reduce((gradeSums, { Grade, Qty }) => 
    gradeSums[Grade] 
        ? { ...gradeSums, [Grade]: gradeSums[Grade] + Number(Qty) } 
        : { ...gradeSums, [Grade]: Number(Qty) }
    , {})
    
console.log(sumGradeArray);

// result:
{
    AU27: 26, 
    FE500D: 242, 
    FE600D: 213
}

Explanation

const sumGradeArray = input.reduce((gradeSums, { Grade, Qty }) => 

Here we perform a reduce. There is a better explanation at the link but essentially we are looping over the array, and saving whatever we return to the first parameter, in this case gradeSums. The second parameter is an item in the array, destructured here for quick access to the properties Grade and Qty.

gradeSums[Grade] 

If we have already saved a value for this grade, then we want to add the value in the current item to what we already have, result in this truthy statement:

? { ...gradeSums, [Grade]: gradeSums[Grade] + Number(Qty) } 

We spread the previous accumulated values so that we do not lose them.

: { ...gradeSums, [Grade]: Number(Qty) }

However, if we have not see it before we create a new entry for the quantity we have just seen.

, {})

Initial value should be an object so that we can spread it successfully.

3 Comments

Not desired result
It's a better result. You haven't provided an explanation for why you want your data structure.
Maheer Ali and Nina Scholz answered as per my requirement

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.