简体   繁体   English

Javascript中新对象数组中数组对象属性值的总和

[英]Sum of array object property values in new array of objects in Javascript

I have an array of objects where i need sum of object property values in new array of objects,我有一个对象数组,我需要新对象数组中对象属性值的总和,

Input:输入:

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' },
  .
  .
  .
];

Output i need,我需要的输出,

var outputArray = [
  { subject: 'Maths', marks: '70', noOfStudents: '17' },
  { subject: 'Science', marks: '115', noOfStudents: '18' },
  { subject: 'History', marks: '95', noOfStudents: '43' },
  .
  .
  .
];

I want sum of marks and no of students of subjects in new object array.我想要新对象数组中的总分和科目的学生人数。 There would be N number of other subject objects (ie-Geography, Physics etc) in the input array.输入数组中将有 N 个其他主题对象(即地理、物理等)。

Simple reduce solution :简单的reduce解决方案:

 const data = [ { 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 result = data.reduce((cur, val) => { let alreadyIn = cur.find(e => e['subject'] == val['subject']); if (alreadyIn) { alreadyIn['marks'] = (parseInt(alreadyIn['marks']) + parseInt(val['marks'])).toString(); alreadyIn['noOfStudents'] = (parseInt(alreadyIn['noOfStudents']) + parseInt(val['noOfStudents'])).toString(); } else { cur.push(val); } return cur; }, []); console.log(result);

You can use forEach() to iterate and generate the new array您可以使用forEach()迭代并生成新数组

 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使用reduce()方法

 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.仅供参考:您可以通过使用find()方法来避免key对象,但在性能方面可能会慢一点。

You can do this with forEach and thisArg optional parameter您可以使用forEachthisArg可选参数执行此操作

 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)

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;
}

The solution using Array.forEach , parseInt and Object.keys functions:使用Array.forEachparseIntObject.keys函数的解决方案:

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
    }
]

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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM