繁体   English   中英

使用嵌套对象展平数组

[英]Flatten an array with nested objects

我有一个带有对象的数组,可以有子节点,子节点与父节点具有相同的结构,它只是对象嵌套。

我想知道如何平整我的对象的结构,所以我有所有对象的id,包括嵌套的对象。

例如,这种结构

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

应该被夷为平地

const data = [2,1,3]

我试过了

使用Array.reduce()和对象传播语法,但我无法绕过执行此操作所需的逻辑。

 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)) 

这是递归的工作。 遍历数组并为其中的每个元素,将id推入一个新数组并为子节点重复。

 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); }); } } 

您可以使用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); 

你可以做一些递归的方法。

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, [])); 

你可以使用recursion.Note传递给arr代码引用,因此我们可以直接push() id到它而不需要获取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,[])) 

我不喜欢递归:)

请注意其他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, "")) ) 

但我希望有人能找到一种方法来一次性忽略非捕获组

您可以通过使用实际ID来减少对象数组并获取其子对象。

 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); 

您可以使用递归方法并为每个children进行迭代,并将所有idid数组中。

 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)); 

另一个版本。 不是最漂亮但完成工作:

 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); 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM