1

I have an array of custom objects which is populated with user inputs. The array looks like this:

let array = [
  {Course: "Design", Hours: "01:00:00", Week: "1"}, 
  {Course: "Design", Hours: "01:00:00", Week: "3"}, 
  {Course: "Design", Hours: "01:00:00", Week: "2"}, 
  {Course: "Design", Hours: "01:00:00", Week: "1"}, 
  {Course: "Design", Hours: "01:00:00", Week: "2"}
]

I need to modify this array so all hours from the same week will be calculated, and the values will be placed in the array according to the order of the weeks. My desired result would be like this:

let newArray = [
  {Course: "Design", Hours: "02:00:00", Week: "1"}, 
  {Course: "Design", Hours: "02:00:00", Week: "2"},
  {Course: "Design", Hours: "01:00:00", Week: "3"},  
]

So basically I need to sort and calculate the sum at the same time.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
egx
  • 389
  • 2
  • 14

1 Answers1

1

You can use moment.js to get the sum of the time strings.

To group the items by week, you can use .reduce.

Finally, to sort the items by Week, use .sort:

let array = [
  {Course: "Design", Hours: "01:00:00", Week: "1"}, 
  {Course: "Design", Hours: "01:00:00", Week: "3"}, 
  {Course: "Design", Hours: "01:00:00", Week: "2"}, 
  {Course: "Design", Hours: "01:00:00", Week: "1"}, 
  {Course: "Design", Hours: "01:00:00", Week: "2"}
];

const addTwoTimeStrs = (a, b) => {
  let sum = moment.duration(a).add(moment.duration(b));
  sum = moment.utc(sum.asMilliseconds()).format("HH:mm:ss");
  return sum;
}

const arr = Object.values(
  array.reduce((acc,item) => {
    const { Hours: hours, Week: week } = item;
    const weekItem = acc[week];
    acc[week] = weekItem
      ? { ...weekItem, Hours: addTwoTimeStrs(weekItem.Hours,hours) }
      : item;
    return acc;
  }, {})
);

const res = arr.sort((a,b) => Number(a.Week) - Number(b.Week));

console.log(res.map(e => e.Hours));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js" integrity="sha512-qTXRIMyZIFb8iQcfjXWCO8+M5Tbc38Qi5WzdPOYZHIlZpzBHG3L3by84BBBOiRGiEb7KKtAOAs5qYdUiZiQNNQ==" crossorigin="anonymous"></script>
Majed Badawi
  • 27,616
  • 4
  • 25
  • 48
  • Thank you. What changes needs to be done if I only want an array with the value of hours? like this: let hours = [02:00:00, 02:00:00, 01:00:00]? – egx Nov 28 '20 at 11:00
  • @egx you are welcome. Please upvote and mark the answer as the solution if it solves the problem. Concerning your question, you can use ``.map`` as follows: ``res.map(e => e.Hours)`` – Majed Badawi Nov 28 '20 at 11:02
  • I will mark it as solved of cause, but it dosent seems to work with the map. I still get an array of objects when I console.log() res. I just need an array with the values of Hours. – egx Nov 28 '20 at 11:05
  • @egx answer updated – Majed Badawi Nov 28 '20 at 11:06