Выравнивание 1 уровня массива объектов и добавление родительского объекта

#javascript #typescript

Вопрос:

У меня есть объект, подобный которому я хочу расплющить:

 const obj = [
    {
      id: 1,
      name: 'parent1',
      children: [ 
          {
            childName: ''child11"
          }
      ]
    },
    {
      id: 2,
      name: 'parent2',
      children: [ 
          {
            childName: ''child21"
          },
          {
            childName: ''child22"
          }
      ]
    }
]
 

Я хочу, чтобы мой объект был таким, как показано ниже:

 eObj = [
    {
        p_id: 1,
        p_name: "parent1",
        childName: "child11"
    },
    {
        p_id: 2,
        p_name: "parent2",
        childName: "child21"
    },
    {
        p_id: 2,
        p_name: "parent2",
        childName: "child22"
    }
]
 

Я сделал это, используя:

       const eObj = [];
      obj.forEach((o) => {
        o.children.forEach((co) => {
          eObj.push({
            p_id: o.id,
            p_name: o.name,
            ...children,
          });
        });
      });
 

Есть ли лучший способ сделать это, а также уменьшить вложенный цикл for? Я был бы вам очень признателен.

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

1. Ваш входной массив недействителен. Проверьте эти цитаты.

2. Если ваша текущая реализация работает, лучшим местом для этого вопроса, вероятно, было бы: codereview.stackexchange.com

Ответ №1:

Если вас интересует, какое решение является более эффективным. Оказывается, ваше двойное forEach решение на самом деле быстрее, чем flatMap amp; map .

flatMap amp; map

 const obj = [{
    id: 1,
    name: "parent1",
    children: [{
      childName: "child11",
    }, ],
  },
  {
    id: 2,
    name: "parent2",
    children: [{
        childName: "child21",
      },
      {
        childName: "child22",
      },
    ],
  },
];

const result = obj.flatMap(({
    children,
    id,
    name
  }) =>
  children.map((child) => ({
    p_id: id,
    p_name: name,
    childName: child.childName,
  }))
);

console.log(result); 

двойной forEach

 const obj = [{
    id: 1,
    name: "parent1",
    children: [{
      childName: "child11",
    }, ],
  },
  {
    id: 2,
    name: "parent2",
    children: [{
        childName: "child21",
      },
      {
        childName: "child22",
      },
    ],
  },
];

const result = [];
obj.forEach((o) => {
  o.children.forEach((co) => {
    result.push({
      p_id: o.id,
      p_name: o.name,
      childName: co.childName,
    });
  });
});

console.log(result); 

JSBench.me сравнение

Ответ №2:

Вы можете использовать плоскую карту. Это работает:

 eObj = obj.flatMap(item => item.children.map(child => ({p_id: item.id, p_name: item.name, childName: child.childName})))
 

Ответ №3:

Каждый способ сделать это требует двухуровневого цикла. Вы можете использовать map или reduce функционировать, и ваш код может быть ясным, но ничто не меняет временной сложности.

Но в этом сценарии вам нужна только map функция:

 const obj = [
    {
      id: 1,
      name: 'parent1',
      children: [ 
          {
            childName: 'child11'
          }
      ]
    },
    {
      id: 2,
      name: 'parent2',
      children: [ 
          {
            childName: 'child21'
          },
          {
            childName: 'child22'
          }
      ]
    }
]



 const eObj = obj.flatMap(t=>t.children.map(c =>  { return {p_id: t.id,p_name: t.name, childName: c.childName}}))

console.log(eObj);