Akhil RJ
Akhil RJ

Reputation: 357

Get Multiple Values from repeated nested JSON

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

Answers (2)

StepUp
StepUp

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

Anton Lee
Anton Lee

Reputation: 694

Maybe you need to use this https://lodash.com/docs#filter, because there is no common solution for your task.

Upvotes: 0

Related Questions