Reputation: 357
I'm trying to fetch values from nested JSON , and this fetching is required for all the data points (Count >1000)
following is the JSON array i want to search on , like i'm getting key
at level 6 from another system and based on the key
i want to extract its value and value of its adjacent parent
like key be 1233
its value will be blah 6
its parent's value will be blah 5
and blah 4
{
"collection": [{
"id": "1:ABC",
"key": "123",
"value": "blah 1",
"children": [{
"id": "2:ABC",
"key": "456",
"value": "blah 2",
"children": [{
"id": "3:ABC",
"key": "987",
"value": "blah 3",
"children": [{
"id": "4:ABC",
"key": "3445",
"value": "blah 4",
"children": [{
"id": "5:ABC",
"key": "7665",
"value": "blah 5",
"children": [{
"id": "6:ABC",
"key": "1233",
"value": "blah 6",
"children": [{
"id": "7:ABC",
"key": "7655",
"value": "blah1 7",
"children": []
}, {
"id": "7:DEF",
"key": "7655",
"value": "blah2 7",
"children": []
}]
}]
}]
}]
}]
}]
}]
}
Updated :
Approach i have implemented:
flattenJSON(actualJSONArrayObj){
const flattenedObj: any = {};
for (const level1 of actualJSONArrayObj) {
for (const level2 of level1.children) {
for (const level3 of level2.children) {
for (const level4 of level3.children) {
for (const level5 of level4.children) {
for (const level6 of level5.children) {
flattenedObj[level6.key] = {
level4:level4.value
level5:level5.value,
level6:level6.value,
}
}
}
}
}
}
}
return flattenedObj;
}
var flattenedObj = flattenJSON(collection);
console.log(flattenedObj['1233'].level4); //output blah 4
Upvotes: 0
Views: 290
Reputation: 38199
You can use Depth First Search Algorithm
to find desired elements in hierarchical data:
const sourceData = {
"id": "1:ABC",
"key": "123",
"value": "blah 1",
"children": [{
"id": "2:ABC",
"key": "456",
"value": "blah 2",
"children": [{
"id": "3:ABC",
"key": "987",
"value": "blah 3",
"children": [{
"id": "4:ABC",
"key": "3445",
"value": "blah 4",
"children": [{
"id": "5:ABC",
"key": "7665",
"value": "blah 5",
"children": [{
"id": "6:ABC",
"key": "1233",
"value": "blah 6",
"children": [{
"id": "7:ABC",
"key": "7655",
"value": "blah1 7",
"children": []
}, {
"id": "7:DEF",
"key": "7655",
"value": "blah2 7",
"children": []
}]
}]
}]
}]
}]
}]
};
and code is:
function test(targetId) {
const desiredItems = getNodeByKey(sourceData, 'blah 5', 'value');
console.log(desiredItems);
}
// Depth First Search Algorithm
function getNodeByKey(obj, targetId, paramKey) {
if (obj[paramKey] == targetId) {
return obj;
}
if (obj.children) {
for (let item of obj.children) {
let check = this.getNodeByKey(item, targetId, paramKey)
if (check) {
return check;
}
}
}
return null
}
console.log(test('blah 5'));
UPDATE:
Usually when we have a hierarchical data, then we have a parent key
in our data:
const sourceData = {
"id": "1:ABC",
"key": "123",
"parentKey": null,
"value": "blah 1",
"children": [{
"id": "2:ABC",
"key": "456",
"parentKey": "123",
"value": "blah 2",
"children": [{
"id": "3:ABC",
"key": "987",
"value": "blah 3",
"parentKey": "456",
"children": [{
"id": "4:ABC",
"key": "3445",
"value": "blah 4",
"parentKey": "987",
"children": [{
"id": "5:ABC",
"key": "7665",
"parentKey": "3445",
"value": "blah 5",
"children": [{
"id": "6:ABC",
"key": "1233",
"parentKey": "7665",
"value": "blah 6",
"children": [{
"id": "7:ABC",
"key": "7655",
"parentKey": "1233",
"value": "blah1 7",
"children": []
}, {
"id": "7:DEF",
"key": "7655",
"parentKey": "1233",
"value": "blah2 7",
"children": []
}]
}]
}]
}]
}]
}]
};
and then you are available get parent object:
function test(targetId) {
const desiredItems = getNodeByKey(sourceData, 'blah 5', 'value');
let parent;
if (desiredItems && desiredItems.parentKey) {
parent = getNodeByKey(sourceData, desiredItems.parentKey, 'key');
}
console.log(desiredItems);
console.log('parent', parent);
}
UPDATE 1:
If you want to get parent node, then you can use this adjusted function to get parent node by children key:
// Depth First Search Algorithm - get parent node
function getParentNodeByChildrenKey(obj, targetId, paramKey) {
if (obj.children) {
if (obj.children.some(ch => ch.value === targetId))
return obj;
else {
for (let item of obj.children) {
let check = this.getParentNodeByChildrenKey(item, targetId, paramKey)
if (check) {
return check;
}
}
}
}
return null
}
and then you are available get parent object by its children key:
function test() {
const parentObjectByChildrenKey = getParentNodeByKey(sourceData, 'blah 5', 'value');
console.log(`parentObjectByChildrenKey is `, parentObjectByChildrenKey);
}
console.log(test());
Upvotes: 1
Reputation: 694
Maybe you need to use this https://lodash.com/docs#filter, because there is no common solution for your task.
Upvotes: 0