Свести массив с вложенными объектами - PullRequest
2 голосов
/ 15 марта 2019

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

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

Например, эта структура

const data = [
  {
    id: 2,
    children: [
      {
        id: 1,
        children: []
      }
    ]
  },
  {
    id: 3,
    children: [],
  }
]

должна быть сведена к этому

const data = [2,1,3]

Я пытался

Используя Array.reduce () и синтаксис распространения объекта, но я не могу обернуться вокруг логики, необходимой для этого.

Ответы [ 9 ]

3 голосов
/ 15 марта 2019

const data = [
  {
    id: 2,
    children: [
      {
        id: 1,
        children: []
      }
    ]
  },
  {
    id: 3,
    children: [],
  }
]

const getIds = (data) => data.map(d => [d.id, ...getIds(d.children)]).flat()

console.log(getIds(data))
2 голосов
/ 15 марта 2019

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

const data = [{
    id: 2,
    children: [{
      id: 1,
      children: []
    }]
  },
  {
    id: 3,
    children: [],
  }
];

console.log(flatten(data));

function flatten(data) {
  const result = [];
  recursive(data);
  return result;

  function recursive(data) {
    data.forEach(member => {
      result.push(member.id);
      recursive(member.children);
    });
  }
}
1 голос
/ 15 марта 2019

Мне не нравятся рекурсии:)

Обратите внимание на другой ответ Stringify - ILST
https://stackoverflow.com/a/55179326/295783

const data=[{id:2,children:[{id:1,children:[]}]},{id:3,children:[],}];

console.log(
  JSON.stringify(data)
    .match(/(?:"id":)(\d+)/g)
    .map(v => +v.replace(/"id":/g, ""))
)

Однако мне бы хотелось, чтобы кто-нибудь нашел мне способ игнорировать не захватывающую группу за один раз

1 голос
/ 15 марта 2019

Вы можете использовать recursion.Note, который находится ниже ссылки на код arr, поэтому мы можем напрямую push() идентифицировать его, и нет необходимости получать return значение

const data = [{ id: 2, children: [{ id: 1, children: [] }] }, { id: 3, children: [], } ]

function getIds(data,arr){
  //iterate over array of chilren
  for(let child of data){
    //add id of each child to arr
    arr.push(child.id);
    //check if child have children add its 'ids' to same array
    if(child.children) getIds(child.children,arr);
  }
  //return array in end
  return arr;
}
console.log(getIds(data,[]))
1 голос
/ 15 марта 2019

Вы можете сделать рекурсивный подход.

function flatArr(arr, res) {
  // iterate over the array
  arr.forEach(o => {
    // check id is present then push it into the result array
    if ('id' in o) res.push(o.id)
    // check children is present and non-empty
    // then ecursively call the function
    if (o.children && o.children.length) flatArr(o.children, res);
  })
  // return the result array(optional)
  return res;
}

console.log(flatArr(data, []));

const data = [{
    id: 2,
    children: [{
      id: 1,
      children: []
    }]
  },
  {
    id: 3,
    children: [],
  }
];

function flatArr(arr, res) {
  // iterate over the array
  arr.forEach(o => {
    // check id is present then push it into the result array
    if ('id' in o) res.push(o.id)
    // check children is present and non-empty
    // then ecursively call the function
    if (o.children && o.children.length) flatArr(o.children, res);
  })
  // return the result array(optional since it's the same array reference you are passing initially)
  return res;
}

console.log(flatArr(data, []));
1 голос
/ 15 марта 2019

Вы можете использовать JSON.stringify, и для каждой клавиши id нажать на массив:

const data = [
  {
    id: 2,
    children: [
      {
        id: 1,
        children: []
      }
    ]
  },
  {
    id: 3,
    children: [],
  }
]
const ids = [];
JSON.stringify(data, (key, val) => {
  if (key === 'id') {
    ids.push(val);
  }
  return val;
});
console.log(ids);
0 голосов
/ 15 марта 2019

Другая версия.Не самая красивая, но выполняет свою работу:

const data = [
    {
        id: 2,
        children: [
            {
                id: 1,
                children: []
            }
        ]
    },
    {
        id: 3,
        children: [],
    }
];
    
let mappedArray = data.map(num => [].concat(num.children.map(child => child.id)).concat(num.id));
    mappedArray = [].concat.apply([], mappedArray);

console.log(mappedArray);
0 голосов
/ 15 марта 2019

Вы можете использовать рекурсивный подход и выполнять итерации для каждого children и помещать все id в массив.

const data = [{ id: 2, children: [{ id: 1, children: [] }] }, { id: 3, children: [], } ],
      getId = (data) => data.reduce((r,{id, children}) => r.concat(id, getId(children)),[]);
console.log(getId(data));
0 голосов
/ 15 марта 2019

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

const
    getId = array => array.reduce(
        (r, { id, children }) => [...r, id, ...getId(children)],
        []
    ),
    data = [{ id: 2, children: [{ id: 1, children: [] }] }, { id: 3, children: [] }],
    ids = getId(data);
    
console.log(ids);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...