I wrote the following function to traverse a JSON-structured data to locate the value of the provided targetField and the paths pathArr, but I am struggling with returning result from the recursion, because the value for the targetField may not exist.
This function uses a global variable named result for returning the targetField's value, but this can get carried over to the next call of findValue(), which may not find the value but shows the last call's result. So I am wondering what's the best way of solving this problem without using the global variable result.
If the call of findValue() does not find the targetField's value, just return null as the result.
The pathArr is something like ["first_level", "second_level", "third_level"];
var result = null;
function findValue(jsonData, pathArr, targetField) {
if (pathArr.length == 0) {
result = targetField in jsonData ? jsonData[targetField] : result;
return result;
} else {
var curNode = pathArr.shift();
if (curNode in jsonData) {
jsonData = jsonData[curNode];
}
if (Array.isArray(jsonData)) {
jsonData.forEach(function(thisData) {
findValue(thisData, pathArr, targetField);
});
} else {
findValue(jsonData, pathArr, targetField);
}
}
return result;
}
Edit: Thanks to everyone who replied.
Using unobf's improved code, I used this testData to do a testing, but it seems only returning the last match:
var testData = {
"num_found" : 3,
"category" : "social",
"groups": [
{"group" : {
"source" : [{"id" : "testID1", "num": 10, "field": "sociaology", "sub-subject" : "socialeconomy"},
{"id" : "testID2", "num": 20, "field": "mathematics", "sub-subject": ""},
{"id" : "testID3", "num": 7, "field": "biology", "sub-subject" : ""}
],
"identifier" : "shelf-01-E-XW1"
}},
{"group" : {
"source" : [{"id" : "testID4", "num": 50, "field": "sociaology2", "sub-subject" : ""},
{"id" : "testID5", "num": 44, "field": "mathematics2", "sub-subject": ""},
{"id" : "testID6", "num": 75, "field": "biology2", "sub-subject" : "european studies2"}
],
"identifier" : "shelf-02-W-EW3"
}},
{"group" : {
"source" : [{"id" : "testID7", "num": 59, "field": "sociaology3", "sub-subject" : "socialeconomy3"},
{"id" : "testID8", "num": 47, "field": "mathematics3", "sub-subject": ""},
{"id" : "testID9", "num": 76, "field": "biology3", "sub-subject" : "european studies3"}
],
"identifier" : "shelf-03-W-GW5"
}}
]
};
and I found I had to change this line of code
return {value : result};
to
return result;
Test:
for (var i = 0; i < testData.groups.length; i++) {
var value = findValue(testData.groups[i], ["group", "source"], "sub-subject");
console.log("found value: " + value);
}
findValuerecursively without returning its return value, instead relying on that call setting a global variable (result)?