Javascript中基于两个对象数组计算的对象数组

Object array based on two object array calculations in Javascript

我必须根据 inputArray 和 factorArray 进行一些计算并创建第三个数组 outputArray。您可以根据主题在 outputArray 属性标记和 noOfStudents 中看到计算部分 属性

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

我需要扩展我之前问题的解决方案:

如果 factorArray 中的 subject 是唯一的:

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

此提案使用临时对象,首先用于 inputArray 的分组结果,然后用于创建 outputArray。这个操作的复杂度是线性的 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);

含计算项的结果

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

我更喜欢像

这样的级联减少

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