'Extract sub-object from nested object typescript
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!
Solution 1:[1]
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))
Solution 2:[2]
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
idexists in the current array - If not, recursive-call for an array of all
childrenof current - If still not found, hard-coded a
-1(may be replaced as"not found", as needed)
Solution 3:[3]
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;
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | R4ncid |
| Solution 2 | jsN00b |
| Solution 3 | Hakim Abdelcadir |
