3
\$\begingroup\$

Output should be an object ({cal: val}), with soonest possible time throughout all calendars recommended times from the data.

My question is: is this approach over complicated and if so, what should be the proper way to solve that task?

Incoming data is an object:

let data = [
  {
    name: "A",
    calendars: {
      "1_A@group.calendar.google.com": {
        busy: ["2019-08-19T14:30:00.000Z"],
        free: [
          {
            start: "2019-08-19T08:00:00.000Z",
            end: "2019-08-19T09:30:00.000Z"
          }
        ],
        recommended: "2019-08-19T01:00:00.000Z"
      },
      "2_A@group.calendar.google.com": {
        busy: ["2019-08-19T14:30:00.000Z"],
        free: [
          {
            start: "2019-08-19T12:30:00.000Z",
            end: "2019-08-19T14:00:00.000Z"
          }
        ],
        recommended: "2019-08-19T04:00:00.000Z"
      }
    }
  },
  {
    name: "B",
    calendars: {
      "1_B@group.calendar.google.com": {
        busy: ["2019-08-19T14:30:00.000Z"],
        free: [
          {
            start: "2019-08-19T12:30:00.000Z",
            end: "2019-08-19T14:00:00.000Z"
          }
        ],
        recommended: "2019-08-19T05:00:00.000Z"
      },
      "2_B@group.calendar.google.com": {
        busy: ["2019-08-19T14:30:00.000Z"],
        free: [
          {
            start: "2019-08-19T12:30:00.000Z",
            end: "2019-08-19T14:00:00.000Z"
          }
        ],
        recommended: "2019-08-19T02:00:00.000Z"
      }
    }
  }
];

Here is how I solved it: https://codesandbox.io/s/purple-rain-ecmcu?fontsize=14

function reduce(data) {
  return data.reduce((acc, cur, i) => {
    if (!acc.length || cur[1] < acc[1]) {
      return [cur[0], new Date(cur[1])];
    } else {
      return acc;
    }
  }, []);
}

data = Object.fromEntries([
  reduce(
    data.map(provider => {
      let providerCalendars = Object.keys(provider.calendars);
      let providerRecommended = Object.values(provider.calendars).map(
        (calendar, i) => [
          providerCalendars[i],
          new Date(calendar.recommended).getTime()
        ]
      );
      return reduce(providerRecommended);
    })
  )
]);
\$\endgroup\$
0
\$\begingroup\$

Minor Changes

  • Method name reduce suggests a generic API method that would take a predicate and accumulator. Instead, it's very specific in returning a custom array and mapping a string to Date. I would call it getCalendarByMinimumRecommendedTime instead.
  • Prefer the use of const over let for immutable data: const providerCalendars and const providerRecommended.
  • The unused index parameter i can be omitted: return data.reduce((acc, cur) => {.
\$\endgroup\$
  • \$\begingroup\$ Ok, thank you! But overall logics is right? I mean reduce method? Or it had to be something different? \$\endgroup\$ – ezik Aug 19 at 9:46
  • \$\begingroup\$ To me it looks fine. Maybe someone knows a better alternative. The only possible issue I would have is that it operates on a custom array, where you need to know what is behind index 0 and what behind 1. \$\endgroup\$ – dfhwze Aug 19 at 10:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.