2

I'm trying to get with Javascript JSON object values to be grouped based on the name key word in the array that contains the objects this is a dynamic array so this cannot be hard coded.

the objects have time values in it

the time_entries array length changes.

the time_entries array can have 1 or more objects in it.

I want to group the objects by the time: Hour minutes seconds

{
    "activities": [
        {
            "name": "player one",
            "time_entries": [
                {
                    "days": 0,
                    "end_time": "2019-09-30 15:19:43",
                    "hours": 01,
                    "minutes": 02,
                    "seconds": 11,
                    "start_time": "2019-09-30 14:17:58"
                },
                {
                    "days": 0,
                    "end_time": "2019-09-25 15:40:11",
                    "hours": 0,
                    "minutes": 20,
                    "seconds": 4,
                    "start_time": "2019-09-25 15:20:15"
                },
                {
                    "days": 0,
                    "end_time": "2019-09-25 16:10:15",
                    "hours": 0,
                    "minutes": 30,
                    "seconds": 4,
                    "start_time": "2019-09-25 15:40:11"
                },

#there can be more objects here

            ]
        },
        {
            "name": "player two",
            "time_entries": [
                {
                    "days": 0,
                    "end_time": "2019-09-30 19:18:51",
                    "hours": 0,
                    "minutes": 0,
                    "seconds": 52,
                    "start_time": "2019-09-30 19:17:58"
                },

#there can be more objects here

            ]
        },
        {
            "name": "player three",
            "time_entries": [
                {
                    "days": 0,
                    "end_time": "2019-09-30 19:19:09",
                    "hours": 0,
                    "minutes": 0,
                    "seconds": 58,
                    "start_time": "2019-09-30 19:18:51"
                },
                {
                    "days": 0,
                    "end_time": "2019-09-30 21:21:09",
                    "hours": 2,
                    "minutes": 1,
                    "seconds": 0,
                    "start_time": "2019-09-30 19:20:09"
                },

#there can be more objects here

            ]
        }
    ]
}

What I want to get is something like this

 [
        {
            "name": "player one",
            "time_entries": [
                {
                    "days": 0,
                    "end_time": "2019-09-25 16:10:15",
                    "hours": 01,
                    "minutes": 50,
                    "seconds": 19,
                    "start_time": "2019-09-30 14:17:58"
                }
            ]
        },
        {
            "name": "player two",
            "time_entries": [
                {
                    "days": 0,
                    "end_time": "2019-09-30 19:18:51",
                    "hours": 0,
                    "minutes": 0,
                    "seconds": 52,
                    "start_time": "2019-09-30 19:17:58"
                }
            ]
        },
        {
            "name": "player three",
            "time_entries": [
                {
                    "days": 0,
                    "end_time":"2019-09-30 21:21:09",
                    "hours": 2,
                    "minutes": 1,
                    "seconds": 58,
                    "start_time": "2019-09-30 19:18:51"
                }
            ]
        }
]

Faseeh Haris
  • 669
  • 1
  • 11
  • 29
Eric. M
  • 170
  • 9
  • 1
    not clear on what you want to achieve. what have you already tried? share the code that you have already tried. [mcve] – Searching Oct 23 '19 at 16:17
  • I'm confusing with your requirements but here are many ways to group your array https://stackoverflow.com/questions/14446511/most-efficient-method-to-groupby-on-an-array-of-objects – André Andrade Oct 23 '19 at 16:19
  • I don't see any _grouping_ going on here. Are you asking how to _combine_ multiple time entries? Your desired output shows only one item in `time_entries` arrays. We need a better description of what you're trying to do. – Jacob Oct 23 '19 at 17:06
  • @Jacob yes im trying to combine multiple time entries? . in the desired output the data from the json data is combined for example the first time_entries array has 3 objects they need to be combined in to 1 object – Eric. M Oct 23 '19 at 17:39
  • @Searching i have only loopd over the data with foreach, i'm new in javascript so i dont know how i can possibly start at this, i hoop maybe i can find a clue here. thanks for the help – Eric. M Oct 23 '19 at 17:42
  • Your sample data still isn't clear. How exactly should they be combined? Do you want `start_time` to be the earliest time and `end_time` to be the latest? The sample output doesn't match that, at least for player 1; is it just a typo? – Jacob Oct 23 '19 at 17:47

1 Answers1

1

You can do it as follows:

  • Use map() method to iterate on given activities and transform each activity's time_entries property.
  • getTimeEntry() method takes array of time entries and returns earliest start time, latest end time, and total activity time converted to days, hours, minutes, seconds.

let data = { "activities": [ { "name": "player one", "time_entries": [ { "days": 0, "end_time": "2019-09-30 15:19:43", "hours": 01, "minutes": 02, "seconds": 11, "start_time": "2019-09-30 14:17:58" }, { "days": 0, "end_time": "2019-09-25 15:40:11", "hours": 0, "minutes": 20, "seconds": 4, "start_time": "2019-09-25 15:20:15" }, { "days": 0, "end_time": "2019-09-25 16:10:15", "hours": 0, "minutes": 30, "seconds": 4, "start_time": "2019-09-25 15:40:11" } ] }, { "name": "player two", "time_entries": [ { "days": 0, "end_time": "2019-09-30 19:18:51", "hours": 0, "minutes": 0, "seconds": 52, "start_time": "2019-09-30 19:17:58" } ] }, { "name": "player three", "time_entries": [ { "days": 0, "end_time": "2019-09-30 19:19:09", "hours": 0, "minutes": 0, "seconds": 58, "start_time": "2019-09-30 19:18:51" }, { "days": 0, "end_time": "2019-09-30 21:21:09", "hours": 2, "minutes": 1, "seconds": 0, "start_time": "2019-09-30 19:20:09" } ] } ] };

let result = {};

result.activities = data.activities.map(item => {
  return {
    "name": item.name,
    "time_entries": [getTimeEntry(item.time_entries)]
  };
});

function getTimeEntry(timeEntries) {
  let earliestTime = timeEntries[0].start_time;
  let latestTime = timeEntries[0].end_time;

  // Find earliest start time and latest end time.
  timeEntries.forEach(entry => {
    if (new Date(entry.start_time) < new Date(earliestTime)) {
      earliestTime = entry.start_time;
    }

    if (new Date(entry.end_time) > new Date(latestTime)) {
      latestTime = entry.end_time;
    }
  });

  // Calculate total seconds.
  let seconds = timeEntries.reduce((totalSeconds, currentEntry) => {
    let seconds = 0;

    seconds += currentEntry.seconds;
    seconds += currentEntry.minutes * 60;
    seconds += currentEntry.hours * 60 * 60;
    seconds += currentEntry.days * 24 * 60 * 60;

    return totalSeconds + seconds;
  }, 0);

  // Convert total seconds to days, hours, minutes, and seconds.
  let days = Math.floor(seconds / (24 * 60 * 60));
  seconds = seconds % (24 * 60 * 60);
  let hours = Math.floor(seconds / (60 * 60));
  seconds = seconds % (60 * 60);
  let minutes = Math.floor(seconds / 60);
  seconds = seconds % 60;

  return {
    "start_time": earliestTime,
    "end_time": latestTime,
    "days": days,
    "hours": hours,
    "minutes": minutes,
    "seconds": seconds
  };
}

console.log(result);
Nikhil
  • 6,493
  • 10
  • 31
  • 68