Reputation: 147
I have to do some calcucations based on inputArray and factorArray and create third array outputArray. You can see caclucations part in outputArray properties marks and noOfStudents based on the subject property
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 factorArray = [
{ subject: 'History', marks: '500', noOfStudents: '200' },
{ subject: 'Maths', marks: '200', noOfStudents: '150' },
{ subject: 'Science', marks: '300', noOfStudents: '100' }
];
var outputArray = [
{ subject: 'Science', marks: '300-(50+65)', noOfStudents: '100-(16+2)' },
{ subject: 'Maths', marks: '200-(40+30)', noOfStudents: '150-(5+12)' },
{ subject: 'History', marks: '500-(35+55)', noOfStudents: '200-(23+20)' }
];
I need to extend the solution to my previous question: https://stackoverflow.com/a/37481705
Upvotes: 0
Views: 72
Reputation: 26161
I would prefer doing by cascaded reduces like
var inar = [{ 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' }],
facar = [{ subject: 'History', marks: '500', noOfStudents: '200' },{ subject: 'Maths', marks: '200', noOfStudents: '150' },{ subject: 'Science', marks: '300', noOfStudents: '100' }];
outar = inar.reduce((p,c) => {var f = p.find(o => o.subject === c.subject);
f ? (f.marks = f.marks*1 + c.marks*1,
f.noOfStudents = f.noOfStudents*1 + c.noOfStudents*1)
: p.push(c);
return p},[])
.reduce((p,c) => {var f = p.find(o => o.subject === c.subject);
f.marks = f.marks*1 - c.marks*1;
f.noOfStudents = f.noOfStudents*1 - c.noOfStudents*1;
return p},facar);
console.log(outar);
Upvotes: 0
Reputation: 386654
This proposal uses a temp object, first for the result of the grouping of inputArray
and later for the creation of outputArray
. The complexity of this operation is linear O(n+m).
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' }],
factorArray = [{ subject: 'History', marks: '500', noOfStudents: '200' }, { subject: 'Maths', marks: '200', noOfStudents: '150' }, { subject: 'Science', marks: '300', noOfStudents: '100' }],
temp = Object.create(null),
outputArray = [];
inputArray.forEach(function (a) {
this[a.subject] = this[a.subject] || { marks: [], noOfStudents: [] };
this[a.subject].marks.push(a.marks);
this[a.subject].noOfStudents.push(a.noOfStudents);
}, temp);
outputArray = factorArray.map(function (a) {
var getSum = function (k) {
return this[a.subject] && this[a.subject][k].length ? '-(' + this[a.subject][k].join('+') + ')' : '';
}.bind(this);
return { subject: a.subject, marks: a.marks + getSum('marks'), noOfStudents: a.noOfStudents + getSum('noOfStudents') };
}, temp);
console.log(outputArray);
Result with calculated items
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' }],
factorArray = [{ subject: 'History', marks: '500', noOfStudents: '200' }, { subject: 'Maths', marks: '200', noOfStudents: '150' }, { subject: 'Science', marks: '300', noOfStudents: '100' }],
temp = Object.create(null),
outputArray = [];
inputArray.forEach(function (a) {
this[a.subject] = this[a.subject] || { marks: 0, noOfStudents: 0 };
this[a.subject].marks += +a.marks;
this[a.subject].noOfStudents += +a.noOfStudents;
}, temp);
outputArray = factorArray.map(function (a) {
var getSum = function (k) {
return (+a[k] - (this[a.subject] && this[a.subject][k] || 0)).toString();
}.bind(this);
return { subject: a.subject, marks: getSum('marks'), noOfStudents: getSum('noOfStudents') };
}, temp);
console.log(outputArray);
Upvotes: 1
Reputation: 5821
If subject
in factorArray
is unique:
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 factorArray = [
{ subject: 'History', marks: '500', noOfStudents: '200' },
{ subject: 'Maths', marks: '200', noOfStudents: '150' },
{ subject: 'Science', marks: '300', noOfStudents: '100' }
];
// the result
var outputArray = [];
// loop through the factors
for(var i = 0, numFactors = factorArray.length; i < numFactors; ++i) {
// this iteration
var thisFactor = factorArray[i];
// make a copy
var thisOutput = {
"subject" : thisFactor.subject,
"marks" : thisFactor.marks,
"noOfStudents" : thisFactor.noOfStudents
};
// loop through the input
for(var j = 0; j < inputArray.length; ++j) {
// this iteration
var thisInput = inputArray[j];
// if the subject matches
if(thisInput.subject == thisOutput.subject) {
// do the calculation
thisOutput.marks -= thisInput.marks;
thisOutput.noOfStudents -= thisInput.noOfStudents;
// we don't need to loop through this one again so remove it from the inputArray
// and decrease j so we check it again on the "next" iteration
inputArray.splice(j--, 1);
}
}
// save it
outputArray.push(thisOutput);
}
console.log(outputArray);
Upvotes: 0