0

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

3
  • is subject in factorArray unique? Commented May 27, 2016 at 16:10
  • 2
    So, what's your question? What part of this are you stuck on? What have you done to try to solve this? Commented May 27, 2016 at 16:13
  • should the result look like that marks: '300-(50+65)', or do you need the result of the calculation marks: '185'? Commented May 27, 2016 at 16:37

3 Answers 3

1

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

Sign up to request clarification or add additional context in comments.

Comments

0

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

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.