简体   繁体   中英

Javascript find all occurrences of name in array of objects and create new unique arrays

I'm trying to get all occurrences from a google calendar in Google Apps Script and create individual arrays for each event name. Simplified version (example) of response array:

{summary=Name1, start={dateTime=2018-12-03T15:00:00+01:00}, end={dateTime=2018-12-03T23:00:00+01:00}},
{summary=Name2, start={dateTime=2018-12-04T11:00:00+01:00}, end={dateTime=2018-12-04T23:00:00+01:00}},
{summary=Name1, start={dateTime=2018-12-05T07:00:00+01:00}, end={dateTime=2018-12-05T15:00:00+01:00}}

What I can't figure out is how to filter/split (whatever you'd call it) this up so I'd end up with a new array with the following format:

EDIT

{Name1=[[2018-12-03, 15, 23, 8.0], [2018-12-04, 11, 23, 12.0], [2018-12-05, 7, 15, 8.0], [2018-12-06, 15, 23, 8.0]], Name2=[[2018-12-11, 7, 16, 9.0], [2018-12-12, 7, 16, 9.0]]}

The idea is to then iterate through this new array and do a foreach to get a list of all the dates for individual names. This is as far as I've gotten

function hoursTally() {
  var calendarId = [CALENDAR_ID];
  var startDay = 24;
  var endDay = 23;
  var month = parseFloat(new Date().getMonth()).toFixed(0);
  var year = new Date().getYear();
  var startDate = new Date( year, month-1, startDay );
  var endDate = new Date( year, month, endDay );
  var optionalArgs = {
    timeMin: startDate.toISOString(),
    timeMax: endDate.toISOString(),
    showDeleted: false,
    singleEvents: true,
    orderBy: 'startTime'
  };
  var response = Calendar.Events.list(calendarId, optionalArgs);
  var events = response.items;
   events.forEach(function(e){
     Logger.log(e);
      var name = e.summary;
      var eventDateStart = new Date(e.start.dateTime);
      var eventDateEnd = new Date(e.end.dateTime);
      var startTime = parseFloat(eventDateStart.getHours()).toFixed(0);
      var endTime = parseFloat(eventDateEnd.getHours()).toFixed(0);
      var theDate = Utilities.formatDate(eventDateStart, 'GMT+1', 'yyyy-MM-dd');
      var total = endTime-startTime;
  });
}

Every attempt of looping the events and getting the aforementioned format has failed :(

Since your stated goal is to collect information from each similarly named event into a single summary object, your output data structure should not be an Array of objects - it should just be an associative object. An Array would be appropriate if you wanted equivalent objects to remain distinct, but you state this is not the case.

The solution is then to reduce the returned events into an object, where the key of the data is the name, and the value is an array of instance information. The instance information is itself an array (in your example, [2018-12-03, 15, 23, 8] )

A simple example which you can adapt to your use case:

const summary = items.reduce(function (obj, item) {
  var name = item.summary;
  // If we haven't seen this name before, initialize an empty array
  if (obj[name] === undefined) { obj[name] = []; }
  ...
  // Create an array with the info we want to store
  var info = [
    eventStartDate,
    ...
  ];
  // Store this info array with all the others for the same name
  obj[name].push(info);
  return obj;
}, {});

You then use this summary by iterating the object:

for (var name in summary) {
  summary[name].forEach(function (info) {
    ...
  });
  ...
}

Array#reduce

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM