How to properly get values from multidimensional object 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) =&gt; {
    if (!acc.length || cur[1] &lt; acc[1]) {
      return [cur[0], new Date(cur[1])];
    } else {
      return acc;
    }
  }, []);
}

data = Object.fromEntries([
  reduce(
    data.map(provider =&gt; {
      let providerCalendars = Object.keys(provider.calendars);
      let providerRecommended = Object.values(provider.calendars).map(
        (calendar, i) =&gt; [
          providerCalendars[i],
          new Date(calendar.recommended).getTime()
        ]
      );
      return reduce(providerRecommended);
    })
  )
]);
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) =&gt; {.