есть ли способ преобразовать вложенный объект в массив в javascript

#javascript

Вопрос:

У меня есть такой объект, как этот

 const input = {
  id: 1,
  name: "nameOne",
  parent: {
    id: 2,
    name: "nameTwo",
    parent: { id: 3, name: "nameThree", parent: null },
  },
}; 

И хотите преобразовать его в массив, подобный этому

 const output = [
  { id: 1, name: "nameOne" },
  { id: 2, name: "nameTwo" },
  { id: 3, name: "nameThree" },
]; 

есть ли какой-нибудь способ сделать это?

Комментарии:

1. да, рекурсивно обрабатывайте объект, создавая выходные данные по ходу

2. function processObject(o) { const output = []; while(o) { const {id, name, parent} = o; output.push({id, name}); o = parent; } return output; }

Ответ №1:

Не знаю, полезно ли это, но вот странный способ добиться этого:

 const input = {
  id: 1,
  name: "nameOne",
  parent: {
    id: 2,
    name: "nameTwo",
    parent: { id: 3, name: "nameThree", parent: null },
  },
};


const result = [...function*(input) {
  do yield { id: input.id, name: input.name }
  while(input = input.parent)
}(input)];

console.log(result); 

Объяснение

То, что он делает, — это не использование рекурсивной функции, а создание IIFE генератора и распространение его в массив, синтаксис:

 [...function*(){ /* code here */ }()]
 

Внутри генератора есть цикл do while, поскольку для тела цикла существует только одна строка, создаются фигурные скобки тела, полный синтаксис:

 do {
  yield { id: input.id, name: input.name }
} while(input = input.parent)
 

Сначала он выдает один объект, содержащий свойство id и name из input (при условии, что объект параметра input имеет по крайней мере один слой). Затем он назначает input.parent input для подготовки следующей итерации: while(input = input.parent) .

Если выражение вычисляет это, означает, что есть еще один слой, поэтому тело цикла снова вычисляется и создает следующий объект для массива, в противном случае функция завершается и закрывает функцию генератора.


Этот подход может показаться короче, но он не очень практичен и труден для понимания, не рекомендуется для реальных проектов.

Ответ №2:

Вы можете легко достичь этого результата с помощью recursion .

 const input = {
  id: 1,
  name: "nameOne",
  parent: {
    id: 2,
    name: "nameTwo",
    parent: {
      id: 3,
      name: "nameThree",
      parent: null
    },
  },
};

function getResult(obj) {
  if (!obj) return;

  const { parent, ...rest } = obj;
  result.push({ ...rest });
  getResult(parent);
}

const result = [];
getResult(input);

console.log(result);