Javascript 中新对象数组中数组对象 属性 值的总和
Sum of array object property values in new array of objects in Javascript
我有一个对象数组,我需要新对象数组中对象 属性 值的总和,
输入:
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' },
.
.
.
];
我需要的输出,
var outputArray = [
{ subject: 'Maths', marks: '70', noOfStudents: '17' },
{ subject: 'Science', marks: '115', noOfStudents: '18' },
{ subject: 'History', marks: '95', noOfStudents: '43' },
.
.
.
];
我想要新对象数组中的分数总和和科目学生人数。输入数组中会有 N 个其他主题对象(即地理、物理等)。
可以使用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);
使用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);
仅供参考: 您可以使用 find()
方法避免 key
对象,但性能方面可能会慢一点。
您可以使用 forEach
和 thisArg
可选参数
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)
给你:
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;
}
使用Array.forEach
、parseInt
和Object.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));
输出:
[
{
"subject": "Maths",
"marks": 70,
"noOfStudents": 17
},
{
"subject": "Science",
"marks": 115,
"noOfStudents": 18
},
{
"subject": "History",
"marks": 90,
"noOfStudents": 43
}
]
只是另一个将对象作为哈希表的提案。
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);
简单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);
我有一个对象数组,我需要新对象数组中对象 属性 值的总和,
输入:
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' },
.
.
.
];
我需要的输出,
var outputArray = [
{ subject: 'Maths', marks: '70', noOfStudents: '17' },
{ subject: 'Science', marks: '115', noOfStudents: '18' },
{ subject: 'History', marks: '95', noOfStudents: '43' },
.
.
.
];
我想要新对象数组中的分数总和和科目学生人数。输入数组中会有 N 个其他主题对象(即地理、物理等)。
可以使用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);
使用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);
仅供参考: 您可以使用 find()
方法避免 key
对象,但性能方面可能会慢一点。
您可以使用 forEach
和 thisArg
可选参数
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)
给你:
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;
}
使用Array.forEach
、parseInt
和Object.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));
输出:
[
{
"subject": "Maths",
"marks": 70,
"noOfStudents": 17
},
{
"subject": "Science",
"marks": 115,
"noOfStudents": 18
},
{
"subject": "History",
"marks": 90,
"noOfStudents": 43
}
]
只是另一个将对象作为哈希表的提案。
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);
简单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);