I have an array with objects, that can have children, the children have the same structure as the parent, it's just object nesting basically.
I'm wondering how I can flatten the structure of my objects so I have the id's of all the objects, including the nested one's.
For example, This structure
const data = [
{
id: 2,
children: [
{
id: 1,
children: []
}
]
},
{
id: 3,
children: [],
}
]
Should be flattened to this
const data = [2,1,3]
Using Array.reduce() and the object spread syntax, but I can't wrap my head around the logic required to do this.
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))
This is a job for recursion. Loop over the array and for each element in it, push the id into a new array and repeat for the children.
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); }); } }
You can use JSON.stringify
, and for each key of id
, push to an array:
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);
You can do some recursive approach.
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, []));
You can use recursion.Note that is below code reference of arr
is passed so we can directly push()
ids to it and no need to get return
value
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,[]))
I do not like recursions :)
Do note the other Stringify answer - 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, "")) )
I however wish someone could find me a way to ignore the non-capturing group in one go
You could reduce the array of objects by using the actual id and get their children objects.
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);
You can use a recursive approach and iterate for each children
and push all the id
in an array.
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));
Another version. Not the prettiest but gets the job done:
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);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.