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

前端 未结 5 950
时光取名叫无心
时光取名叫无心 2020-11-27 23:41

I have an array of objects where i need sum of object property values in new array of objects,

Input:

var inputArray = [
  { subject: \'Maths\', mark         


        
相关标签:
5条回答
  • 2020-11-28 00:21

    The solution using Array.forEach, parseInt and Object.keys functions:

    var summed = {}, result;
    inputArray.forEach(function (obj) {
        obj['marks'] = parseInt(obj['marks']);
        obj['noOfStudents'] = parseInt(obj['noOfStudents']);
        var subj = obj['subject'];
    
        if (!summed[subj]) {
            summed[subj] = obj;
        } else {
            summed[subj]['marks'] += obj['marks'];
            summed[subj]['noOfStudents'] += obj['noOfStudents'];
        }
    }, summed);
    result = Object.keys(summed).map((k) => summed[k]);
    
    console.log(JSON.stringify(result, 0, 4));
    

    The output:

    [
        {
            "subject": "Maths",
            "marks": 70,
            "noOfStudents": 17
        },
        {
            "subject": "Science",
            "marks": 115,
            "noOfStudents": 18
        },
        {
            "subject": "History",
            "marks": 90,
            "noOfStudents": 43
        }
    ]
    
    0 讨论(0)
  • 2020-11-28 00:26

    Just another proposal with an object as hashtable.

    var inputArray = [{ 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' }],
        outputArray = [];
    inputArray.forEach(function (a) {
        if (!this[a.subject]) {
            this[a.subject] = { subject: 'Maths', marks: '0', noOfStudents: '0' };
            outputArray.push(this[a.subject]);
        }
        this[a.subject].marks = (+this[a.subject].marks + +a.marks).toString();
        this[a.subject].noOfStudents = (+this[a.subject].noOfStudents + +a.noOfStudents).toString();
    }, Object.create(null));
    
    console.log(outputArray);

    0 讨论(0)
  • 2020-11-28 00:30

    You can do this with forEach and thisArg optional parameter

    var inputArray = [
      { 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' },
    ], outputArray = [];
      
    inputArray.forEach(function(e) {
      if(!this[e.subject]) {
        this[e.subject] = { subject: e.subject, marks:  0, noOfStudents: 0 }
         outputArray.push(this[e.subject]);
       }
      this[e.subject].marks += Number(e.marks);
      this[e.subject].noOfStudents += Number(e.noOfStudents);
    }, {});
    
    console.log(outputArray)

    0 讨论(0)
  • 2020-11-28 00:33

    Here you go:

    function convert(inputArray) {
        var temp = {};
        for(var i = 0; i < inputArray.length; i++) {
            var subject = inputArray[i].subject;
    
            // check if there is already an entry with this subject in the temp array
            if(temp.hasOwnProperty(subject)) {
                // if it is already in the list, add the marks and the noOfStudents
                temp[subject].marks = temp[subject].marks + parseInt(inputArray[i].marks, 10);
                temp[subject].noOfStudents = temp[subject].noOfStudents + parseInt(inputArray[i].noOfStudents, 10);
            }
            else {
                // if it is not yet in the list, add a new object
                temp[subject] = {
                    subject: subject,
                    marks: parseInt(inputArray[i].marks, 10),
                    noOfStudents: parseInt(inputArray[i].noOfStudents, 10)
                }
            }
        }
    
        // the temporary array is based on the subject, you are however interested on the effective value object
        var result = [];
        for(var entryKey in temp) {
            result.push(temp[entryKey]);
        }
    
        return result;
    }
    
    0 讨论(0)
  • 2020-11-28 00:34

    You can use forEach() to iterate and generate the new array

    var inputArray = [
      { 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' }
    ],
        res = [],
        key = {};
    
    inputArray.forEach(function(v) {
      if (key.hasOwnProperty(v.subject)) { // check subject already added by using key object
        res[key[v.subject]].marks += Number(v.marks); //incase already exist parse number and add
        res[key[v.subject]].noOfStudents += Number(v.noOfStudents);
      } else {
        key[v.subject] = res.length; // create index entry in key object
        res.push({ // push the value 
          'subject': v.subject,
          'marks': Number(v.marks),
          'noOfStudents': Number(v.noOfStudents)
        })
        // if you pushed the original object then the original array also will get updated while adding the mark, so never push the refernce
      }
    })
    
    console.log(res);


    Using reduce() method

    var inputArray = [
      { 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' }
    ],
        key = {};
    
    res=inputArray.reduce(function(arr,v) {
      if (key.hasOwnProperty(v.subject)) { // check subject already added by using key object
        arr[key[v.subject]].marks += Number(v.marks); //incase already exist parse number and add
        arr[key[v.subject]].noOfStudents += Number(v.noOfStudents);
      } else {
        key[v.subject] = arr.length; // create index entry in key object
        arr.push({ // push the value 
          'subject': v.subject,
          'marks': Number(v.marks),
          'noOfStudents': Number(v.noOfStudents)
        })
        // if you pushed the original object then the original array also will get updated while adding the mark, so never push the refernce     
      }
      return arr;
    },[])
    
    console.log(res);


    FYI : You can avoid the key object by using find() method, but performance wise that may be little bit slower.

    0 讨论(0)
提交回复
热议问题