как сгладить массив объекта до нескольких уровней?

#javascript

#javascript

Вопрос:

У меня есть массив объектов, внутри которого находится несколько массивов объектов, подгруппы могут быть до n-го уровня, и я хочу сгладить его до одного массива объектов.

Ввод

 obj = [{ id: a1, name: "apple", subGroups:  [{id: a2, name: "apple-a", subGroups: {id: a3, name: "apple-b", subGroups:  [{id: a4, name: "apple-c", subGroups: {id: a5, name: "apple-d", subGroups:[]}}]}}]}]
  

Ожидаемый результат

 [{ id: a1, name: "apple"}, {id: a2, name: "apple-a"}, {id: a3, name: "apple-b"}, {id: a4, name: "apple-c"},{id: a5, name: "apple-d"}]
  

Я использовал плоскую карту и уменьшение, но я могу сгладить только до второго уровня. пожалуйста, помогите

 const arr = obj.reduce(
      (arr, elem) => [...arr, ...elem.subGroups], []
    )
    console.log(arr)
  

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

1. Некоторые из ваших подгрупп являются массивами, а некоторые — объектами. Действительно ли так располагаются данные?

Ответ №1:

Вам понадобится рекурсия. Я предполагаю, что здесь это subGroups всегда массив (или неопределенный / нулевой):

 let obj = [{ id: "a1", name: "apple", subGroups:  [{id: "a2", name: "apple-a", subGroups: [{id: "a3", name: "apple-b", subGroups:  [{id: "a4", name: "apple-c", subGroups: [{id: "a5", name: "apple-d", subGroups:[]}]}]}]}]}]

const flatten = (groups) => 
    (groups || []).flatMap(({subGroups, ...o}) => [o, ...flatten(subGroups)]);

console.log(flatten(obj));  

Ответ №2:

Это можно сделать рекурсивно следующим образом.

 const input = [{
  id: "a1",
  name: "apple",
  subGroups: [{
    id: "a2",
    name: "apple-a",
    subGroups: [{
      id: "a3",
      name: "apple-b",
      subGroups: [{
        id: "a4",
        name: "apple-c",
        subGroups: [{
          id: "a5",
          name: "apple-d",
          subGroups: []
        }]
      }]
    }]
  }]
}];

function loopValues(val) {
  let q = [];
  val.forEach(elm => {
    if(elm == null) {
      return;
    }
    
    const { subGroups, ...rest } = elm;
    q = [...q, rest, ...loopValues(subGroups)];
  });
  return q;
}

const output = loopValues(input);
console.log(output);  

Ответ №3:

 function flatten(array, currentArray) {
  if (!array) return currentArray;

  return array.reduce((acumulatedArray, currentElement) => {
    const { subGroups, ...element } = currentElement;
    return [...acumulatedArray, element, ...flatten(subGroups, [])];
  }, currentArray);
}

// Or width flatMap

function flatten(array, currentArray) {
  if (!array) return currentArray;

  return [...array.flatMap((currentElement) => {
    const { subGroups, ...element } = currentElement;
    return [element, ...flatten(subGroups, [])];
  }), ...currentArray];
}

const res = flatten(
  [
    {
      id: "a1",
      name: "apple",
      subGroups: [
        {
          id: "a2",
          name: "apple-a",
          subGroups: [
            {
              id: "a3",
              name: "apple-b",
              subGroups: [
                {
                  id: "a4",
                  name: "apple-c",
                  subGroups: [{ id: "a5", name: "apple-d", subGroups: [] }],
                },
              ],
            },
          ],
        },
      ],
    },
  ],
  []
);

console.log(res);