Is there a way to extract a sub-object from a nested object?
For example I have the following object:
[
{
id: 370,
name: 'FY 2022',
children: [
{
id: 371,
name: 'Q1 2022',
children: [
{
id: 409,
name: 'Jan 2022',
},
{
id: 410,
name: 'Feb 2022',
},
{
id: 411,
name: 'Mar 2022',
},
],
},
],
},
];
if I send in a function as a parameter the id
to return me the object corresponding with that id.
For example if I give as parameter id = 371 to return me:
[
{
id: 371,
name: 'Q1 2022',
children: [
{
id: 409,
name: 'Jan 2022',
},
{
id: 410,
name: 'Feb 2022',
},
{
id: 411,
name: 'Mar 2022',
},
],
},
];
or if I give the id = 410 to return:
[
{
id: 410,
name: 'Feb 2022',
},
];
Thanks in advance!
CodePudding user response:
You can do something like this
const findById = (data, id) => {
if(data.length === 0){
return []
}
const el = data.find(d => d.id === id)
if(el){
return [el]
}
return findById(data.flatMap(d => d.children || []), id)
}
const data = [
{
id: 370,
name: 'FY 2022',
children: [
{
id: 371,
name: 'Q1 2022',
children: [
{
id: 409,
name: 'Jan 2022',
},
{
id: 410,
name: 'Feb 2022',
},
{
id: 411,
name: 'Mar 2022',
},
],
},
],
},
];
console.log(findById(data, 370))
console.log(findById(data, 409))
console.log(findById(data, 4090))
CodePudding user response:
This is one possible solution using recursion to achieve the desired objective.
Code Snippet
const findUsingId = (searchId, arr) => (
[
arr.find(({ id }) => id === searchId) ||
findUsingId(searchId, (arr.flatMap(({ children }) => children))) ||
-1
].flat()
);
const origArr = [{
id: 370,
name: 'FY 2022',
children: [{
id: 371,
name: 'Q1 2022',
children: [{
id: 409,
name: 'Jan 2022',
},
{
id: 410,
name: 'Feb 2022',
},
{
id: 411,
name: 'Mar 2022',
},
],
}, ],
}, ];
console.log('id: 371', findUsingId(371, origArr));
console.log('id: 410', findUsingId(410, origArr));
console.log('id: 370', findUsingId(370, origArr));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Explanation
- First, wrap the potential result within an array
[]
and apply.flat()
so it is not nested. - Check if
id
exists in the current array - If not, recursive-call for an array of all
children
of current - If still not found, hard-coded a
-1
(may be replaced as"not found"
, as needed)
CodePudding user response:
You can create a recursive function to process the whole object until it finds the right one. If you want to do it with typescript I would also create an interface to define a structure of the object. The final result will be this:
interface IObject = {
id: number;
name: string;
children?: IObject[];
}
function find(yourObject: IObject[], id: number) : IObject {
let result : IObject;
for(const obj of yourObject){
const {id : idObj, children} = obj;
if(idObj === id){
result = obj;
}
else if(children){
result = find(children, id);
}
if(result){
break;
}
}
return result;
}