wrarar wrarar - 1 month ago 7
Javascript Question

How to cummulative sum of array inside map function?

I am totally confused that how to implement cummulative array.I think the best way to do this in reduce method.But i am little confused with that
Currently my output will look like this..
thanks in advance

output

Jobs Inserted ====================>
JobId:j8 Time to finish this Job :32
JobId:j7 Time to finish this Job :22
JobId:j2 Time to finish this Job :9
JobId:j5 Time to finish this Job :8
JobId:j4 Time to finish this Job :7
JobId:j6 Time to finish this Job :5
JobId:j1 Time to finish this Job :4
JobId:j3 Time to finish this Job :1
Machines Available :4
Output =====================================>
//I want the result should be cummulative array
MachineId:M1 Jobs done By this Machine:(j5 = 8),(j4 = 7),(j3 = 1) Time consumed to finish all jobs:16
MachineId:M2 Jobs done By this Machine:(j2 = 9),(j6 = 5),(j1 = 4) Time consumed to finish all jobs:18
MachineId:M3 Jobs done By this Machine:(j7 = 22) Time consumed to finish all jobs:22
MachineId:M4 Jobs done By this Machine:(j8 = 32) Time consumed to finish all jobs:32



Ex:-j5=8,j4=7+8=15,j3=16


like this

MachineId:M1 Jobs done By this Machine:(j5 = 8),(j4 = 15),(j3 = 16) Time consumed to finish all jobs:16
MachineId:M2 Jobs done By this Machine:(j2 = 9),(j6 = 14),(j1 = 18) Time consumed to finish all jobs:18
MachineId:M3 Jobs done By this Machine:(j7 = 22) Time consumed to finish all jobs:22
MachineId:M4 Jobs done By this Machine:(j8 = 32) Time consumed to finish all jobs:32


How to implement this...
this is my source code

var _ = require('underscore');
var njobs = [{
jobname: "j1",
time: 4
}, {
jobname: "j2",
time: 9
}, {
jobname: "j3",
time: 1
}, {
jobname: "j4",
time: 7
}, {
jobname: "j5",
time: 8
}, {
jobname: "j6",
time: 5
}, {
jobname: "j7",
time: 22
},
{
jobname: "j8",
time: 32
}

];

//sort this data with time
var sorted = njobs.sort((a, b) => b.time - a.time);

console.log('Jobs Inserted ====================>')

sorted.map(function (data) {
console.log('JobId:'+data.jobname+' Time to finish this Job :'+data.time)
});

//List all the machines
var machines = [
{
id:1,
value:0,
jobs:[],
name:'M1'
},
{
id:2,
value:0,
jobs:[],
name:'M2'
},
{
id:3,
value:0,
jobs:[],
name:'M3'
},
{
id:3,
value:0,
jobs:[],
name:'M4'
}
];
console.log('Machines Available :'+ machines.length);
//Loop it and assign it
sorted.forEach(job => {
var minMachine = machines
.slice(1)
.reduce((res, cur) =>
res.value < cur.value ? res : cur, machines[0]);

minMachine.jobs.push(job);
minMachine.value += job.time;
});


//Prints the value

console.log('Output =====================================>');



machines.map(function (data) {
console.log('MachineId:'+data.name+' Jobs done By this Machine:'+data.jobs.map(data => '('+data.jobname+' = '+data.time+')')+' Time consumed to finish all jobs:'+data.value)
});



var high = Math.max.apply(Math,machines.map(function (o) {
return o.value;
}));
console.log('______________________________________________')
console.log('Highest Time consuming Machine =========>');
var result = _.findWhere(machines,{value:high});
console.log(result.name+' is the highest running Machine '+result.value);

Answer

Okay, so I found your issue. In this case, you will need to build the string piece by piece, appending each job number and the current running total of time as you go. You can do this with the .reduce() function as mentioned before, or you can create a variable that keeps the total, and use a basic forEach(). The reduce() will be much cleaner, but the forEach() may be easier to understand if you were to refactor the code in the future - honestly it's your choice. Here's how I did it using reduce():

Let me know if you have any questions!

machines.map(function (data) {
  var str = "MachineId:" + data.name + " Jobs done by this Machine:"
  data.jobs.reduce(function (total, curr){
    var newTotal = total + curr.time;
    str += "("+curr.jobname+" = "+newTotal+")";
    return newTotal;
  }, 0);
  str += ' Time consumed to finish all jobs:'+data.value;
  console.log(str);
});

Fully Working DEMO

var njobs = [{
  jobname: "j1",
  time: 4
}, {
  jobname: "j2",
  time: 9
}, {
  jobname: "j3",
  time: 1
}, {
  jobname: "j4",
  time: 7
}, {
  jobname: "j5",
  time: 8
}, {
  jobname: "j6",
  time: 5
}, {
  jobname: "j7",
  time: 22
}, {
  jobname: "j8",
  time: 32
}];

//sort this data with time
var sorted = njobs.sort((a, b) => b.time - a.time);

console.log('Jobs Inserted ====================>')

sorted.map(function(data) {
  console.log('JobId:' + data.jobname + ' Time to finish this Job :' + data.time)
});

//List all the machines
var machines = [{
  id: 1,
  value: 0,
  jobs: [],
  name: 'M1'
}, {
  id: 2,
  value: 0,
  jobs: [],
  name: 'M2'
}, {
  id: 3,
  value: 0,
  jobs: [],
  name: 'M3'
}, {
  id: 3,
  value: 0,
  jobs: [],
  name: 'M4'
}];
console.log('Machines Available :' + machines.length);
//Loop it and assign it
sorted.forEach(job => {
  var minMachine = machines
    .slice(1)
    .reduce((res, cur) =>
      res.value < cur.value ? res : cur, machines[0]);

  minMachine.jobs.push(job);
  minMachine.value += job.time;
});


//Prints the value

console.log('Output =====================================>');



machines.map(function(data) {
  var str = "MachineId:" + data.name + " Jobs done by this Machine:"
  data.jobs.reduce(function(total, curr) {
    var newTotal = total + curr.time;
    str += "(" + curr.jobname + " = " + newTotal + ")";
    return newTotal;
  }, 0);
  str += ' Time consumed to finish all jobs:' + data.value;
  console.log(str);
});



var high = Math.max.apply(Math, machines.map(function(o) {
  return o.value;
}));
console.log('______________________________________________')
console.log('Highest Time consuming Machine =========>');
var result = _.findWhere(machines, {
  value: high
});
console.log(result.name + ' is the highest running Machine  ' + result.value);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore.js"></script>

Comments