I am trying to build an array of JSON objects for FancyTree (https://github.com/mar10/fancytree/wiki/TutorialLoadData). However, my JSON source (Jira REST service) can have pretty much any structure, so the code to build the array of JSON objects has to be entirely generic and able to handle pretty much anything.
Here is an example of the source JSON:
{
"feed": {
"entry": [
{
"expand": "renderedFields,names,schema,operations,editmeta,changelog,versionedRepresentations",
"id": "95743",
"self": "foo.comjira/rest/api/2/issue/95743",
"key": "XYZ-24600",
"fields": {
"MandatoryReviewersInternal": [
{
"self": "foo.comjira/rest/api/2/customFieldOption/10947",
"value": "Test",
"id": "10947",
"disabled": false
}
],
"PlannedDropDate": "2022-02-01",
"assignee": {
"self": "foo.comjira/rest/api/2/user?username=swchambe",
"name": "swchambe",
"key": "swchambe",
"emailAddress": "sharon.w.chamberlain#foo.com",
"displayName": "Sharon W Chamberlain",
"active": true,
"timeZone": "America/Chicago"
},
"ESBEnvironments": {
"self": "foo.comjira/rest/api/2/customFieldOption/10120",
"value": "All Environments",
"id": "10120",
"disabled": false
},
"RestrictedInformation": "Do not include Proprietary, ITAR or SBU restricted information in this action",
"subtasks": [
{
"id": "96160",
"key": "XYZ-24601",
"self": "foo.comjira/rest/api/2/issue/96160",
"fields": {
"summary": "Test 1",
"status": {
"self": "foo.comjira/rest/api/2/status/10338",
"description": "",
"iconUrl": "foo.comjira/images/icons/statuses/generic.png",
"name": "Current",
"id": "10338",
"statusCategory": {
"self": "foo.comjira/rest/api/2/statuscategory/4",
"id": 4,
"key": "indeterminate",
"colorName": "yellow",
"name": "In Progress"
}
},
"issuetype": {
"self": "foo.comjira/rest/api/2/issuetype/10319",
"id": "10319",
"description": "",
"iconUrl": "foo.comjira/secure/viewavatar?size=xsmall&avatarId=11747&avatarType=issuetype",
"name": "Affected Document",
"subtask": true,
"avatarId": 11747
}
}
},
{
"id": "96466",
"key": "XYZ-24614",
"self": "foo.comjira/rest/api/2/issue/96466",
"fields": {
"summary": "Test 2",
"status": {
"self": "foo.comjira/rest/api/2/status/10338",
"description": "",
"iconUrl": "foo.comjira/images/icons/statuses/generic.png",
"name": "Current",
"id": "10338",
"statusCategory": {
"self": "foo.comjira/rest/api/2/statuscategory/4",
"id": 4,
"key": "indeterminate",
"colorName": "yellow",
"name": "In Progress"
}
},
"issuetype": {
"self": "foo.comjira/rest/api/2/issuetype/10319",
"id": "10319",
"description": "",
"iconUrl": "foo.comjira/secure/viewavatar?size=xsmall&avatarId=11747&avatarType=issuetype",
"name": "Affected Document",
"subtask": true,
"avatarId": 11747
}
}
}
],
"Participants": [
{
"name": "djcook2(djcook2xyz)"
},
{
"name": "swchambe(swchambexyz)"
},
{
"name": "r_slscdm(JIRAxyz)"
}
],
"reporter": {
"self": "foo.comjira/rest/api/2/user?username=djcook2",
"name": "djcook2",
"key": "djcook2",
"emailAddress": "deborah.j.ott#foo.com",
"displayName": "Deborah Jane Ott",
"active": true,
"timeZone": "America/Chicago"
},
"CPEOrganization": "xyz",
"SFSearchandViewLink": "<a href=foo.comportal/web/csa/search?key=95743&projectKey=XYZ&issueType=Change%20Request>S2D-0637</a>",
"progress": {
"progress": 0,
"total": 0
},
"issuetype": {
"self": "foo.comjira/rest/api/2/issuetype/8",
"id": "8",
"description": "Request for a change to the way the application works.",
"iconUrl": "foo.comjira/secure/viewavatar?size=xsmall&avatarId=11737&avatarType=issuetype",
"name": "Change Request",
"subtask": false,
"avatarId": 11737
},
"project": {
"self": "foo.comjira/rest/api/2/project/13390",
"id": "13390",
"key": "XYZ",
"name": "Configuration Status Accounting",
"projectTypeKey": "business"
},
"SFIdentifier": "S2D-0637",
"watches": {
"self": "foo.comjira/rest/api/2/issue/XYZ-24600/watchers",
"watchCount": 2,
"isWatching": true
},
"ServerEnvironment": [
{
"self": "foo.comjira/rest/api/2/customFieldOption/10060",
"value": "Production",
"id": "10060",
"disabled": false
}
],
"ScheduleImpact": {
"self": "foo.comjira/rest/api/2/customFieldOption/12245",
"value": "No",
"id": "12245",
"disabled": false
},
"MissionConfigurationDefinition": [
{
"self": "foo.comjira/rest/api/2/customFieldOption/12246",
"value": "1110-1200",
"id": "12246",
"disabled": false
},
{
"self": "foo.comjira/rest/api/2/customFieldOption/12247",
"value": "1110-2200",
"id": "12247",
"disabled": false
}
],
"updated": "2022-05-23T10:06:45.000-0500",
"description": "¶ Paragraph\nNonbreaking Hyphen\nEm Space\nEn Space\n½ One Half Fraction\n¼ One Quarter Fraction\n¾ Three Quarters Fraction\n10⁵ superscript\n6⁵ superscript\nO₂ subscript\n\n± 0177\n≤ 2264\n≥ 2265\n\n10⁰ - 2070\n10¹ - 00B9\n10³ - 00B3\n10² - 00B2\n10⁴ - 2074\n10⁵ - 2075\n10⁶ - 2076\n10⁷ - 2077\n10⁸ - 2078\n10⁹ - 2079\n\nΑ 0391\nΒ 0392\nΓ 0393\nΔ 0394\nΕ 0395",
"CRStatus": {
"self": "foo.comjira/rest/api/2/customFieldOption/10050",
"value": "In Work",
"id": "10050",
"disabled": false
},
"summary": "SLS-FSW-SAN-21-0010 SLS FSW Software Authorization Notice (SAN) - PARMD5 Support Tool Release 14.0",
"SLSPriority": {
"self": "foo.comjira/rest/api/2/customFieldOption/10347",
"value": "Routine",
"id": "10347",
"disabled": false
},
"TestStatus": [
{
"self": "foo.comjira/rest/api/2/customFieldOption/10041",
"value": "Not Tested",
"id": "10041",
"disabled": false
}
],
"ChangeJustificationRationale": "Looks good to me, but who am I?",
"CostImpact": {
"self": "foo.comjira/rest/api/2/customFieldOption/19251",
"value": "No",
"id": "19251",
"disabled": false
},
"ExternalReviewType": {
"self": "foo.comjira/rest/api/2/customFieldOption/10370",
"value": "Mandatory",
"id": "10370",
"disabled": false
},
"CROffice": {
"self": "foo.comjira/rest/api/2/customFieldOption/10342",
"value": "SLS",
"id": "10342",
"disabled": false
},
"Rank": "0|i0c9r8:",
"CrossProgram": {
"self": "foo.comjira/rest/api/2/customFieldOption/10294",
"value": "No",
"id": "10294",
"disabled": false
},
"Programassignedto": {
"self": "foo.comjira/rest/api/2/customFieldOption/10295",
"value": "SLS",
"id": "10295",
"disabled": false
},
"Programassignedby": {
"self": "foo.comjira/rest/api/2/customFieldOption/10301",
"value": "SLS",
"id": "10301",
"disabled": false
},
"ChangeType": [
{
"self": "foo.comjira/rest/api/2/customFieldOption/10307",
"value": "Programmatic",
"id": "10307",
"disabled": false
}
],
"ChangePackageManagerCPM": {
"self": "foo.comjira/rest/api/2/user?username=swchambe",
"name": "swchambe",
"key": "swchambe",
"emailAddress": "sharon.w.chamberlain#foo.com",
"displayName": "Sharon W Chamberlain",
"active": true,
"timeZone": "America/Chicago"
},
"ChangePackageManagerAlternateCPMAlternate": {
"self": "foo.comjira/rest/api/2/user?username=slcraig",
"name": "slcraig",
"key": "smclemo2",
"emailAddress": "shanda.craig#foo.com",
"displayName": "Shanda L Craig",
"active": true,
"timeZone": "America/Chicago"
},
"ChangePackageEngineerCPE": {
"self": "foo.comjira/rest/api/2/user?username=cbowab",
"name": "cbowab",
"key": "cbowab",
"emailAddress": "cheri.f.bowab#foo.com",
"displayName": "Cheri F Bowab",
"active": true,
"timeZone": "America/Chicago"
},
"status": {
"self": "foo.comjira/rest/api/2/status/10631",
"description": "",
"iconUrl": "foo.comjira/images/icons/statuses/generic.png",
"name": "Draft",
"id": "10631"
},
"Development": "{}",
"RequestedDate": "2021-05-13",
"Risk": {
"self": "foo.comjira/rest/api/2/customFieldOption/10273",
"value": "No",
"id": "10273",
"disabled": false
},
"creator": {
"self": "foo.comjira/rest/api/2/user?username=djcook2",
"name": "djcook2",
"key": "djcook2",
"emailAddress": "deborah.j.ott#foo.com",
"displayName": "Deborah Jane Ott",
"active": true,
"timeZone": "America/Chicago"
},
"aggregateprogress": {
"progress": 0,
"total": 0
},
"AssigneeSecurityScan": {
"self": "foo.comjira/rest/api/2/user?username=sbattles",
"name": "sbattles",
"key": "sbattles",
"emailAddress": "sylvia.battles#foo.com",
"displayName": "Sylvia M Battles",
"active": true,
"timeZone": "America/Chicago"
},
"Board": [
{
"self": "foo.comjira/rest/api/2/customFieldOption/10259",
"value": "XYZ",
"id": "10259",
"disabled": false
}
],
"MissionEffectivity": [
{
"self": "foo.comjira/rest/api/2/customFieldOption/19754",
"value": "XYZ",
"id": "19754",
"disabled": false
},
{
"self": "foo.comjira/rest/api/2/customFieldOption/19756",
"value": "AC01",
"id": "19756",
"disabled": false
}
],
"CRNumber": [
{
"name": "XYZ-0637"
}
],
"created": "2021-05-14T15:14:22.000-0500",
"ASCBBoardDate": "2021-05-18",
"InitiatorOrganization": "ED10",
"CPMAssignedDate": "2021-05-14",
"CRAssignedDate": "2021-05-14",
"ImpactstoCertifiedData": {
"self": "foo.comjira/rest/api/2/customFieldOption/20152",
"value": "No",
"id": "20152",
"disabled": false
},
"ASCBReviewSuspenseDate": "2021-05-18",
"TopLevelLinkTitle": "SV02854 S2D-0637",
"TopLevelLinkURL": "https://nasa-ice.nasa.gov/Windchill/app/#ptc1/tcomp/infoPage?ContainerOid=OR%3Awt.inf.library.WTLibrary%3A3451955009&oid=OR%3Awt.folder.SubFolder%3A4352888087&u8=1",
"Initiator": {
"self": "foo.comjira/rest/api/2/user?username=kmoorhea",
"name": "kmoorhea",
"key": "kmoorhea",
"emailAddress": "kathy.h.moorhead#foo.com",
"displayName": "Kathy H Moorhead",
"active": true,
"timeZone": "America/Chicago"
}
}
}
]
}
}
I need to end up with an array of JSON objects that looks like this:
[
{title: "Node 1", key: "1"},
{title: "Folder 2", key: "2", folder: true, children: [
{title: "Node 2.1", key: "3", myOwnAttr: "abc"},
{title: "Node 2.2", key: "4"},
{title: "Folder 3", key: "5", folder: true, children: [
{title: "Node 3.1", key: "6", myOwnAttr: "xyz"},
{title: "Node 3.2", key: "7"}
]}
]}
]
Here is my current attempt. It is not working as desired.
const createTreeJson = function(){
let treeJson = [];
let treeJsonObj = {};
//loop entry array, but there is only ever 1
feedJson.feed.entry.forEach((entry) => {
treeJsonObj = {};
//items
treeJsonObj.title = "Item";
treeJsonObj.folder = true;
let children = [];
//loop object properties
Object.entries(entry).forEach(([key, value]) => {
children.push(createTreeJsonObject(children, key, value));
});
treeJsonObj.children = children;
treeJson.push(treeJsonObj);
});
console.log(treeJson);
}
const createTreeJsonObject = function(children, key, value){
console.log(key, value);
if(value.constructor.name === "Object"){
//it's an object
let subChildren = [];
Object.entries(value).forEach(([key2, value2]) => {
subChildren.push(createTreeJsonObject(subChildren, key2, value2));
});
children.push({
"title": key,
"folder": true,
"children": subChildren
});
}else if(value.constructor.name === "Array"){
//it's an array
}else{
//it's something else
children.push({
"key": key,
"title": `${key}`,
"tooltip": `${value}`
});
}
return children;
};
createTreeJson();
Note: feedJson in the code is the above source JSON. I did not want to repeat it again in the code. You can also see it in a Fiddle here: https://jsfiddle.net/ua8vm9p7/1/
I am open to using something like loadash to help with this if it makes it easier. I do have jQuery available too, but am trying to stay away from it.
I can't seem to quite get the logic right. Has anyone done this kind of thing before? Can anyone lend a hand on how I can do it?
Thanks.
I think simpler code will do this:
const makeFancyMenu = (obj) =>
Object .entries (obj) .flatMap (([k, v]) =>
Array .isArray (v)
? []
: Object (v) === v
? [{title: k, folder: true, children: makeFancyMenu (v)}]
: [{key: k, title: `${k}`, tooltip: v}]
)
const convert = (obj) =>
obj .feed .entry .map ((o) => ({
title: 'Item',
folder: true,
children: makeFancyMenu (o)
}))
const input = {feed: {entry: [{expand: "renderedFields,names,schema,operations,editmeta,changelog,versionedRepresentations", id: "95743", self: "foo.comjira/rest/api/2/issue/95743", key: "XYZ-24600", fields: {MandatoryReviewersInternal: [{self: "foo.comjira/rest/api/2/customFieldOption/10947", value: "Test", id: "10947", disabled: !1}],PlannedDropDate: "2022-02-01", assignee: {self: "foo.comjira/rest/api/2/user?username=swchambe", name: "swchambe", key: "swchambe", emailAddress: "sharon.w.chamberlain#foo.com", displayName: "Sharon W Chamberlain", active: !0,timeZone: "America/Chicago"},ESBEnvironments: {self: "foo.comjira/rest/api/2/customFieldOption/10120", value: "All Environments", id: "10120", disabled: !1},RestrictedInformation: "Do not include Proprietary, ITAR or SBU restricted information in this action", subtasks: [{id: "96160", key: "XYZ-24601", self: "foo.comjira/rest/api/2/issue/96160", fields: {summary: "Test 1", status: {self: "foo.comjira/rest/api/2/status/10338", description: "", iconUrl: "foo.comjira/images/icons/statuses/generic.png", name: "Current", id: "10338", statusCategory: {self: "foo.comjira/rest/api/2/statuscategory/4", id: 4,key: "indeterminate", colorName: "yellow", name: "In Progress"}},issuetype: {self: "foo.comjira/rest/api/2/issuetype/10319", id: "10319", description: "", iconUrl: "foo.comjira/secure/viewavatar?size=xsmall&avatarId=11747&avatarType=issuetype", name: "Affected Document", subtask: !0,avatarId: 11747}}},{id: "96466", key: "XYZ-24614", self: "foo.comjira/rest/api/2/issue/96466", fields: {summary: "Test 2", status: {self: "foo.comjira/rest/api/2/status/10338", description: "", iconUrl: "foo.comjira/images/icons/statuses/generic.png", name: "Current", id: "10338", statusCategory: {self: "foo.comjira/rest/api/2/statuscategory/4", id: 4,key: "indeterminate", colorName: "yellow", name: "In Progress"}},issuetype: {self: "foo.comjira/rest/api/2/issuetype/10319", id: "10319", description: "", iconUrl: "foo.comjira/secure/viewavatar?size=xsmall&avatarId=11747&avatarType=issuetype", name: "Affected Document", subtask: !0,avatarId: 11747}}}],Participants: [{name: "djcook2(djcook2xyz)"},{name: "swchambe(swchambexyz)"},{name: "r_slscdm(JIRAxyz)"}],reporter: {self: "foo.comjira/rest/api/2/user?username=djcook2", name: "djcook2", key: "djcook2", emailAddress: "deborah.j.ott#foo.com", displayName: "Deborah Jane Ott", active: !0,timeZone: "America/Chicago"},CPEOrganization: "xyz", SFSearchandViewLink: "<a href=foo.comportal/web/csa/search?key=95743&projectKey=XYZ&issueType=Change%20Request>S2D-0637</a>", progress: {progress: 0,total: 0},issuetype: {self: "foo.comjira/rest/api/2/issuetype/8", id: "8", description: "Request for a change to the way the application works.", iconUrl: "foo.comjira/secure/viewavatar?size=xsmall&avatarId=11737&avatarType=issuetype", name: "Change Request", subtask: !1,avatarId: 11737},project: {self: "foo.comjira/rest/api/2/project/13390", id: "13390", key: "XYZ", name: "Configuration Status Accounting", projectTypeKey: "business"},SFIdentifier: "S2D-0637", watches: {self: "foo.comjira/rest/api/2/issue/XYZ-24600/watchers", watchCount: 2,isWatching: !0},ServerEnvironment: [{self: "foo.comjira/rest/api/2/customFieldOption/10060", value: "Production", id: "10060", disabled: !1}],ScheduleImpact: {self: "foo.comjira/rest/api/2/customFieldOption/12245", value: "No", id: "12245", disabled: !1},MissionConfigurationDefinition: [{self: "foo.comjira/rest/api/2/customFieldOption/12246", value: "1110-1200", id: "12246", disabled: !1},{self: "foo.comjira/rest/api/2/customFieldOption/12247", value: "1110-2200", id: "12247", disabled: !1}],updated: "2022-05-23T10: 06: 45.000-0500", description: "¶ Paragraph\nNonbreaking Hyphen\nEm Space\nEn Space\n½ One Half Fraction\n¼ One Quarter Fraction\n¾ Three Quarters Fraction\n10⁵ superscript\n6⁵ superscript\nO₂ subscript\n\n± 0177\n≤ 2264\n≥ 2265\n\n10⁰ - 2070\n10¹ - 00B9\n10³ - 00B3\n10² - 00B2\n10⁴ - 2074\n10⁵ - 2075\n10⁶ - 2076\n10⁷ - 2077\n10⁸ - 2078\n10⁹ - 2079\n\nΑ 0391\nΒ 0392\nΓ 0393\nΔ 0394\nΕ 0395", CRStatus: {self: "foo.comjira/rest/api/2/customFieldOption/10050", value: "In Work", id: "10050", disabled: !1},summary: "SLS-FSW-SAN-21-0010 SLS FSW Software Authorization Notice (SAN) - PARMD5 Support Tool Release 14.0", SLSPriority: {self: "foo.comjira/rest/api/2/customFieldOption/10347", value: "Routine", id: "10347", disabled: !1},TestStatus: [{self: "foo.comjira/rest/api/2/customFieldOption/10041", value: "Not Tested", id: "10041", disabled: !1}],ChangeJustificationRationale: "Looks good to me, but who am I?", CostImpact: {self: "foo.comjira/rest/api/2/customFieldOption/19251", value: "No", id: "19251", disabled: !1},ExternalReviewType: {self: "foo.comjira/rest/api/2/customFieldOption/10370", value: "Mandatory", id: "10370", disabled: !1},CROffice: {self: "foo.comjira/rest/api/2/customFieldOption/10342", value: "SLS", id: "10342", disabled: !1},Rank: "0|i0c9r8: ", CrossProgram: {self: "foo.comjira/rest/api/2/customFieldOption/10294", value: "No", id: "10294", disabled: !1},Programassignedto: {self: "foo.comjira/rest/api/2/customFieldOption/10295", value: "SLS", id: "10295", disabled: !1},Programassignedby: {self: "foo.comjira/rest/api/2/customFieldOption/10301", value: "SLS", id: "10301", disabled: !1},ChangeType: [{self: "foo.comjira/rest/api/2/customFieldOption/10307", value: "Programmatic", id: "10307", disabled: !1}],ChangePackageManagerCPM: {self: "foo.comjira/rest/api/2/user?username=swchambe", name: "swchambe", key: "swchambe", emailAddress: "sharon.w.chamberlain#foo.com", displayName: "Sharon W Chamberlain", active: !0,timeZone: "America/Chicago"},ChangePackageManagerAlternateCPMAlternate: {self: "foo.comjira/rest/api/2/user?username=slcraig", name: "slcraig", key: "smclemo2", emailAddress: "shanda.craig#foo.com", displayName: "Shanda L Craig", active: !0,timeZone: "America/Chicago"},ChangePackageEngineerCPE: {self: "foo.comjira/rest/api/2/user?username=cbowab", name: "cbowab", key: "cbowab", emailAddress: "cheri.f.bowab#foo.com", displayName: "Cheri F Bowab", active: !0,timeZone: "America/Chicago"},status: {self: "foo.comjira/rest/api/2/status/10631", description: "", iconUrl: "foo.comjira/images/icons/statuses/generic.png", name: "Draft", id: "10631"},Development: "{}", RequestedDate: "2021-05-13", Risk: {self: "foo.comjira/rest/api/2/customFieldOption/10273", value: "No", id: "10273", disabled: !1},creator: {self: "foo.comjira/rest/api/2/user?username=djcook2", name: "djcook2", key: "djcook2", emailAddress: "deborah.j.ott#foo.com", displayName: "Deborah Jane Ott", active: !0,timeZone: "America/Chicago"},aggregateprogress: {progress: 0,total: 0},AssigneeSecurityScan: {self: "foo.comjira/rest/api/2/user?username=sbattles", name: "sbattles", key: "sbattles", emailAddress: "sylvia.battles#foo.com", displayName: "Sylvia M Battles", active: !0,timeZone: "America/Chicago"},Board: [{self: "foo.comjira/rest/api/2/customFieldOption/10259", value: "XYZ", id: "10259", disabled: !1}],MissionEffectivity: [{self: "foo.comjira/rest/api/2/customFieldOption/19754", value: "XYZ", id: "19754", disabled: !1},{self: "foo.comjira/rest/api/2/customFieldOption/19756", value: "AC01", id: "19756", disabled: !1}],CRNumber: [{name: "XYZ-0637"}],created: "2021-05-14T15: 14: 22.000-0500", ASCBBoardDate: "2021-05-18", InitiatorOrganization: "ED10", CPMAssignedDate: "2021-05-14", CRAssignedDate: "2021-05-14", ImpactstoCertifiedData: {self: "foo.comjira/rest/api/2/customFieldOption/20152", value: "No", id: "20152", disabled: !1},ASCBReviewSuspenseDate: "2021-05-18", TopLevelLinkTitle: "SV02854 S2D-0637", TopLevelLinkURL: "https: //nasa-ice.nasa.gov/Windchill/app/#ptc1/tcomp/infoPage?ContainerOid=OR%3Awt.inf.library.WTLibrary%3A3451955009&oid=OR%3Awt.folder.SubFolder%3A4352888087&u8=1", Initiator: {self: "foo.comjira/rest/api/2/user?username=kmoorhea", name: "kmoorhea", key: "kmoorhea", emailAddress: "kathy.h.moorhead#foo.com", displayName: "Kathy H Moorhead", active: !0,timeZone: "America/Chicago"}}}]}}
console .log (convert (input))
.as-console-wrapper {max-height: 100% !important; top: 0}
Here, makeFancyMenu does all the recursive heavy lifting, and convert simply wraps it in something that handles the differences at the root.
Instead of map we use flatMap and wrap its single callback returns in arrays so that in the case of an array property, we can just return an empty array. This is a simple way to combine filter and map.
Is it possible to use the find() method within an array of depth x?
For example, suppose I have the following array of objects, call it test:
[
{
"id": "1",
"title": "First",
},
{
"id": "2",
"title": "Second",
"movies": [
{
"id": "3",
"title": "Happy Gilmore",
"Actors": [
{
"id": "4",
"title": "John Doe",
},
{
"id": "5",
"title": "Jane Doe",
},
],
"Producers": [
{
"id": "6",
"title": "Max Smith",
},
{
"id": "7",
"title": "Richard Rocky",
},
],
},
{
"id": "10",
"title": "Billy Madison",
"Actors": [
{
"id": "40",
"title": "John Smith",
},
{
"id": "50",
"title": "Alex Doe",
},
],
"Producers": [
{
"id": "60",
"title": "Bob Smith",
},
{
"id": "70",
"title": "Polly Rocky",
},
],
}
]
}
]
Suppose I am looking for the "2" id. I can use the find() method to search the first level of the array and return the desired object by doing test.find(element => element.id === "2").
However, suppose I am now looking for the occurrence where the id is 4. As you can see from the above JSON, that element is within a sub array within test. Is there a way therefore where I can still search through test to find the element where id=4?
find cannot do this, but you can use it in a recursive approach:
function findDeep(arr, predicate) {
let res = arr.find(predicate);
if (res !== undefined) return res;
for (let obj of arr) {
for (let value of Object.values(Object(obj)).filter(Array.isArray)) {
res = findDeep(value, predicate);
if (res !== undefined) return res;
}
}
}
let test = [{"id": "1","title": "First",},{"id": "2","title": "Second","movies": [{"id": "3","title": "Happy Gilmore","Actors": [{"id": "4","title": "John Doe",},{"id": "5","title": "Jane Doe",},],"Producers": [{"id": "6","title": "Max Smith",},{"id": "7","title": "Richard Rocky",},],},{"id": "10","title": "Billy Madison","Actors": [{"id": "40","title": "John Smith",},{"id": "50","title": "Alex Doe",},],"Producers": [{"id": "60","title": "Bob Smith",},{"id": "70","title": "Polly Rocky",},],}]}];
let res = findDeep(test, obj => obj.id == "4");
console.log(res);