Sum of array object property values in new array of objects in JavaScript

When working with arrays of objects, we often need to group objects by a common property and sum up their numeric values. This is particularly useful when dealing with student records, sales data, or any scenario where duplicate categories need to be consolidated.

Suppose we have an array of objects that contains data about students and their marks:

const arr = [
  { subject: 'Maths', marks: '40', noOfStudents: '5' },
  { subject: 'Science', marks: '50', noOfStudents: '16' },
  { subject: 'History', marks: '35', noOfStudents: '23' },
  { subject: 'Science', marks: '65', noOfStudents: '2' },
  { subject: 'Maths', marks: '30', noOfStudents: '12' },
  { subject: 'History', marks: '55', noOfStudents: '20' },
];

console.log("Original array:", arr);
Original array: [
  { subject: 'Maths', marks: '40', noOfStudents: '5' },
  { subject: 'Science', marks: '50', noOfStudents: '16' },
  { subject: 'History', marks: '35', noOfStudents: '23' },
  { subject: 'Science', marks: '65', noOfStudents: '2' },
  { subject: 'Maths', marks: '30', noOfStudents: '12' },
  { subject: 'History', marks: '55', noOfStudents: '20' }
]

We need to eliminate redundant entries based on the 'subject' property and sum the marks and number of students for each unique subject. The expected output should be:

[
  { subject: 'Maths', marks: 70, noOfStudents: 17 },
  { subject: 'Science', marks: 115, noOfStudents: 18 },
  { subject: 'History', marks: 90, noOfStudents: 43 }
]

Using reduce() with Object Mapping

The most efficient approach uses the reduce() method combined with an object to track unique subjects:

const arr = [
  { subject: 'Maths', marks: '40', noOfStudents: '5' },
  { subject: 'Science', marks: '50', noOfStudents: '16' },
  { subject: 'History', marks: '35', noOfStudents: '23' },
  { subject: 'Science', marks: '65', noOfStudents: '2' },
  { subject: 'Maths', marks: '30', noOfStudents: '12' },
  { subject: 'History', marks: '55', noOfStudents: '20' },
];

const groupBySubject = (arr = []) => {
  const map = {};
  
  return arr.reduce((acc, val) => {
    const { subject, marks, noOfStudents } = val;
    
    if (map.hasOwnProperty(subject)) {
      // Subject already exists, add to existing values
      acc[map[subject]]['marks'] += +marks;
      acc[map[subject]]['noOfStudents'] += +noOfStudents;
    } else {
      // New subject, create new entry
      map[subject] = acc.length;
      acc.push({
        subject: subject,
        marks: +marks,
        noOfStudents: +noOfStudents
      });
    }
    return acc;
  }, []);
};

console.log(groupBySubject(arr));
[
  { subject: 'Maths', marks: 70, noOfStudents: 17 },
  { subject: 'Science', marks: 115, noOfStudents: 18 },
  { subject: 'History', marks: 90, noOfStudents: 43 }
]

Alternative Approach Using Map

We can also use ES6 Map for cleaner syntax:

const groupWithMap = (arr = []) => {
  const subjectMap = new Map();
  
  arr.forEach(({ subject, marks, noOfStudents }) => {
    if (subjectMap.has(subject)) {
      const existing = subjectMap.get(subject);
      existing.marks += +marks;
      existing.noOfStudents += +noOfStudents;
    } else {
      subjectMap.set(subject, {
        subject,
        marks: +marks,
        noOfStudents: +noOfStudents
      });
    }
  });
  
  return Array.from(subjectMap.values());
};

console.log(groupWithMap(arr));
[
  { subject: 'Maths', marks: 70, noOfStudents: 17 },
  { subject: 'Science', marks: 115, noOfStudents: 18 },
  { subject: 'History', marks: 90, noOfStudents: 43 }
]

How It Works

Both approaches follow the same logic:

  1. Track unique subjects: Use an object or Map to store references to unique subjects
  2. Check for duplicates: For each array element, check if the subject already exists
  3. Sum values: If it exists, add the numeric values to the existing entry; otherwise, create a new entry
  4. Type conversion: Use the unary plus operator (+) to convert string numbers to integers

Key Points

  • The +marks syntax converts string values to numbers for proper addition
  • Object destructuring makes the code more readable and concise
  • The reduce() method is ideal for transforming arrays into new structures
  • Using a map object helps track array indices efficiently

Conclusion

Both approaches effectively group array objects by a common property and sum numeric values. The reduce() method with object mapping is more traditional, while the Map approach offers cleaner ES6 syntax for similar functionality.

Updated on: 2026-03-15T23:19:00+05:30

754 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements