[英]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
进行迭代,并将所有id
推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));
另一个版本。 不是最漂亮但完成工作:
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.