Q: Как получить объект с вложенной структурой из массива JS Есть массив:
response.data = [{year:2020, month:7, day:16, hour:12, minute:0, title:"Задача"},{...},{...}];

Как можно преобразовать исходный массив response.data в объект tasks со следующей структурой:
{
 '2020': {
    '7': {
      '16': {
        '12': {
          '0': 'Заголовок'
        }   
      },
      '17': {
        '12': {
          '0': 'Заголовок 2'
        }   
      }
    }
  }
}

Ожидается примерно что-то такое:
const tasks = {};
response.data.forEach((task) => {
  tasks[task.year][task.month][task.day][task.hour][task.minute] = task.title;
});

Но, естественно, так не работает.
Может быть существует какой-то оптимальный способ?
UPD. Пока реализовал следующим образом:
const tasks = {};
  response.data.forEach((task) => {
    if (task) {
      if (!tasks[task.year]) tasks[task.year] = {};
      if (!tasks[task.year][task.month]) tasks[task.year][task.month] = {};
      if (!tasks[task.year][task.month][task.day]) tasks[task.year][task.month][task.day] = {};
      if (!tasks[task.year][task.month][task.day][task.hour]) tasks[task.year][task.month][task.day][task.hour] = {};
      if (!tasks[task.year][task.month][task.day][task.hour][task.minute]) tasks[task.year][task.month][task.day][task.hour][task.minute] = [];
    
    tasks[task.year][task.month][task.day][task.hour][task.minute].push(task.title);
  }
});

Выглядит глупо, но хотя бы работает.

A: Если вам нужен универсальный способ, если вы уверены, что порядок ключей в объектах всегда один и тот же и среда исполнения соблюдает этот порядок при итерации, можно попробовать так:


const data1 = [
  {year: 2020, month: 7, day: 16, hour: 12, minute: 0, title: 'Заголовок 1'},
  {year: 2020, month: 7, day: 17, hour: 12, minute: 0, title: 'Заголовок 2'},
];

const data2 = {};

for (const entry of data1) {
  let currentObject = data2;

  const values = Object.values(entry);
  const title = values.pop();
  const lastIndex = values.length - 1;

  values.forEach((value, index) => {
    if (index < lastIndex) {
      if (!currentObject[value]) currentObject[value] = {};
      currentObject = currentObject[value];
    } else {
      currentObject[value] = title;
    }
  });
}

console.log(JSON.stringify(data2, null, '  '));


Чуть менее универсально, но безоппаснее:


const data1 = [
  {year: 2020, month: 7, day: 16, hour: 12, minute: 0, title: 'Заголовок 1'},
  {year: 2020, month: 7, day: 17, hour: 12, minute: 0, title: 'Заголовок 2'},
];

const data2 = {};

for (const entry of data1) {
  let currentObject = data2;

  const values = [entry.year, entry.month, entry.day, entry.hour, entry.minute];
  const title = entry.title;
  const lastIndex = values.length - 1;

  values.forEach((value, index) => {
    if (index < lastIndex) {
      if (!currentObject[value]) currentObject[value] = {};
      currentObject = currentObject[value];
    } else {
      currentObject[value] = title;
    }
  });
}

console.log(JSON.stringify(data2, null, '  '));


