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.
Related
I'm trying to sort/arrange array based on nested object value.
Current array :
const comments = [{
"id": 1745,
"bannerId": 35002,
"content": "lorem ipsum",
"user": "John Doe",
"banner": {
"format": "300x250",
"lang": "EN"
}
},
{
"id": 1747,
"bannerId": 35002,
"content": "test 2222",
"user": "John Doe",
"banner": {
"format": "300x250",
"lang": "EN"
}
},
{
"id": 1750,
"bannerId": 35002,
"content": "test 3333",
"user": "Frank Doe",
"banner": {
"format": "300x250",
"lang": "EN"
}
},
{
"id": 1744,
"bannerId": 35004,
"content": "bla bla",
"user": "John Doe",
"banner": {
"format": "300x600",
"lang": "EN"
}
},
{
"id": 1746,
"bannerId": 35006,
"content": "tesssttt",
"user": "Frank Doe",
"banner": {
"format": "970x250",
"lang": "NL"
}
}];
I googled many documents for sorting nested object, but I couldn't find the way of my case and I struggled so many hours so I want to ask to how can I sort above array of objects.
Desired output (or something like this) :
const comments = [{
"EN" : [{
"300x250" : [{
"John Doe" : [
{"id": 1745, "bannerId": 35002, "comment": "lorem ipsum"},
{"id": 1747, "bannerId": 35002, "comment": "test 2222"}
]
},{
"Frank Doe" : [
{"id": 1750, "bannerId": 35002, "comment": "test 3333"}
]
}]
},{
"300x600" : [{
"John Doe" : [
{"id": 1744, "bannerId": 35004, "comment": "bla bla"}
]
}]
}]
},{
"NL" : [{
"970x250" : [{
"Frank Doe" : [
{"id": 1746, "bannerId": 35006, "comment": "tesssttt"}
]
}]
}]
}];
I've already tried this without success :
let list = [];
for (let i = 0; i < comments.length; i++) {
list[comments[i].banner.lang] = [{
[comments[i].banner.format] : [{
[comments[i].user] : [{
'id': comments[i].id, 'bannerId': comments[i].bannerId, 'comments' : comments[i].content
}]
}]
}];
}
The "=" overwrite the previous data..
There is something i messed up but i can't figured out :s
Hope someone here can help me :)
You could find the nested items of the grouping arrays.
This approach takes an array of functions for getting the right key value at the wanted level.
const
data = [{ id: 1745, bannerId: 35002, content: "lorem ipsum", user: "John Doe", banner: { format: "300x250", lang: "EN" } }, { id: 1747, bannerId: 35002, content: "test 2222", user: "John Doe", banner: { format: "300x250", lang: "EN" } }, { id: 1750, bannerId: 35002, content: "test 3333", user: "Frank Doe", banner: { format: "300x250", lang: "EN" } }, { id: 1744, bannerId: 35004, content: "bla bla", user: "John Doe", banner: { format: "300x600", lang: "EN" } }, { id: 1746, bannerId: 35006, content: "tesssttt", user: "Frank Doe", banner: { format: "970x250", lang: "NL" } }],
groups = [o => o.banner.lang, o => o.banner.format, o => o.user],
result = data.reduce((r, o) => {
groups
.reduce((level, fn) => {
let key = fn(o),
p = level.find(q => key in q);
if (!p) level.push(p = { [key]: [] });
return p[key];
}, r)
.push({ id: o.id, bannerId: o.bannerId, comment: o.content });
return r;
}, []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
let list = [];
for (let i = 0; i < comments.length; i++) {
if (!list[comments[i].banner.lang]) {
list[comments[i].banner.lang] = [];
}
if (!list[comments[i].banner.lang][comments[i].banner.format]) {
list[comments[i].banner.lang][comments[i].banner.format] = [];
}
if (!list[comments[i].banner.lang][comments[i].banner.format][comments[i].user]) {
list[comments[i].banner.lang][comments[i].banner.format][comments[i].user] = [];
}
list[comments[i].banner.lang][comments[i].banner.format][comments[i].user].push({
'id': comments[i].id,
'bannerId': comments[i].bannerId,
'comment' : comments[i].content
});
}
Regardless of the JSON object structure (simple or complex) what would be the ideal method to extract all urls from the following object into an array to iterate over in Javascript?
{
"url": "https://example.com:443/-/media/images/site/info",
"data": [
{
"id": "da56fac6-6907-4055-96b8-f8427d4c64fd",
"title": "AAAA 2021",
"time": "",
"dateStart": "2021-03-01T08:00:00Z",
"dateEnd": "2021-12-31T15:00:00Z",
"address": "",
"geo": {
"longitude": "",
"latitude": "",
"mapExternalLink": ""
},
"price": "Free Admission",
"masonryImage": "https://example.com:443/-/media/images/site/siteimages/tcsm2021/fullwidthbanner/tcsmfullwidthicecream.ashx",
"image": "https://example.com:443/-/media/images/site/siteimages/tcsm2021/fullwidthbanner/tcsmfullwidthicecream.ashx",
"showDateInfo": false,
"showDateInfoOnListings": false,
"showTimeInfo": false,
"showTimeInfoOnListings": false,
"tags": [
{
"key": "Lifestyle",
"name": "Lifestyle"
}
],
"partnerName": "",
"sort_data": {
"recommended": 0,
"recent": 3,
"partner": 0,
"popular": 0
}
}
]
}
I would like to get the results in an array such as:
[
https://example.com:443/-/media/images/site/info,https://example.com:443/-/media/images/site/siteimages/tcsm2021/fullwidthbanner/tcsmfullwidthicecream.ashx, https://example.com:443/-/media/images/site/siteimages/tcsm2021/fullwidthbanner/tcsmfullwidthicecream.ashx
]
I gather that i would need to apply some regex to extract the urls but not sure how to treat the json object as string for regex processing?
I think the better and easier way is to stringfy given json into string and solve it by regex.
But still if you need to solve it by recursive, try the codes below:
const obj = {
url: "https://example.com:443/-/media/images/site/info",
data: [
{
id: "da56fac6-6907-4055-96b8-f8427d4c64fd",
title: "AAAA 2021",
time: "",
dateStart: "2021-03-01T08:00:00Z",
dateEnd: "2021-12-31T15:00:00Z",
address: "",
geo: {
longitude: "",
latitude: "",
mapExternalLink: "",
},
price: "Free Admission",
masonryImage:
"https://example.com:443/-/media/images/site/siteimages/tcsm2021/fullwidthbanner/tcsmfullwidthicecream.ashx",
image: "https://tw.yahoo.com",
showDateInfo: false,
showDateInfoOnListings: false,
showTimeInfo: false,
showTimeInfoOnListings: false,
tags: [
{
key: "Lifestyle",
name: "Lifestyle",
link: "https://www.google.com",
},
],
partnerName: "",
sort_data: {
recommended: 0,
recent: 3,
partner: 0,
popular: 0,
anotherObj: {
link: "https://www.github.com",
},
},
},
],
};
function getUrl(obj) {
const ary = [];
helper(obj, ary);
return ary;
}
function helper(item, ary) {
if (typeof item === "string" && isUrl(item)) {
ary.push(item);
return;
} else if (typeof item === "object") {
for (const k in item) {
helper(item[k], ary);
}
return;
}
return null;
}
function isUrl(str) {
if (typeof str !== "string") return false;
return /http|https/.test(str);
}
console.log(getUrl(obj));
But if you use this solution you need to transfer your json into js object
i'd agree to use a JSON parser, but if you want to do it with a regular expression, you might try this
console.log(JSON.stringify({
"url": "https://example.com:443/-/media/images/site/info",
"data": [{
"id": "da56fac6-6907-4055-96b8-f8427d4c64fd",
"title": "AAAA 2021",
"time": "",
"dateStart": "2021-03-01T08:00:00Z",
"dateEnd": "2021-12-31T15:00:00Z",
"address": "",
"geo": {
"longitude": "",
"latitude": "",
"mapExternalLink": ""
},
"price": "Free Admission",
"masonryImage": "https://example.com:443/-/media/images/site/siteimages/tcsm2021/fullwidthbanner/tcsmfullwidthicecream.ashx",
"image": "https://example.com:443/-/media/images/site/siteimages/tcsm2021/fullwidthbanner/tcsmfullwidthicecream.ashx",
"showDateInfo": false,
"showDateInfoOnListings": false,
"showTimeInfo": false,
"showTimeInfoOnListings": false,
"tags": [{
"key": "Lifestyle",
"name": "Lifestyle"
}],
"partnerName": "",
"sort_data": {
"recommended": 0,
"recent": 3,
"partner": 0,
"popular": 0
}
}]
}).match(/(?<=")https?:\/\/[^\"]+/g));
(?<=")https?:\/\/[^\"]+ basically finds patterns that start with a protocol scheme (http:// or https:// preceded by a " character) followed by anything that is not "
I had reformat my data in mongodb using ancestors path to ensure the relationship of each nodes & intend to show it in a organisation tree view.
[
{
"isActive": true,
"ancestorsPath": [],
"studentGroup": [
"t2-001",
"t2-002",
"t2-003"
],
"_id": "33d9704f34901855c911e433",
"email": "user5#test.com",
"agentId": "t1-001"
},
{
"isActive": true,
"ancestorsPath": [],
"studentGroup": [
"t2-101",
"t2-102",
"t2-103"
],
"_id": "5cdb0664c409e90e4fe21133",
"email": "user5#test.com",
"agentId": "t1-100",
},
{
"isActive": true,
"ancestorsPath": [
"t1-001"
],
"studentGroup": [
"t3-001",
"t3-002",
"t3-003"
],
"_id": "5cdb06dec409e90e4fe21134",
"email": "user5#test.com",
"agentId": "t2-001",
}
]
However the data in organisation tree is using a format as below:
id: "T1-001",
name: "user5#test.com",
title: "general manager",
children: [
{
id: "t2-001",
name: "Bo Miao",
title: "department manager",
number: "MYR 2,000"
},
{
id: "t2-002",
name: "Su Miao",
title: "department manager",
children: [
{ id: "t3-001", name: "Tie Hua", title: "senior engineer" },
{
id: "t3-002",
name: "Hei Hei",
title: "senior engineer",
children: [
{ id: "6", name: "Pang Pang", title: "engineer" },
{ id: "7", name: "Xiang Xiang", title: "UE engineer" }
]
}
]
},
{ id: "t2-003", name: "Hong Miao", title: "department manager" }
How should I format my data? Can anyone give me some pointers so i can study further?
Hello I am trying to figure out how to get the object with a specific id from an array with mutlitple levels. The array will have objects, these objects may have arrays with objects as values. For example see the data given below:
[
{
"id": "e1f015d3-4ca8-4dfd-839d-bed9bbbb82f8",
"text": "Parent Menu 2",
"icon": "e1f015d3-4ca8-4dfd-839d-bed9bbbb82f8/rose-3142529__340.jpg",
"page_type": "parent_menu",
"data": "e1f015d3-4ca8-4dfd-839d-bed9bbbb82f8",
"ui_config": "",
"order": 2
},
{
"id": "5bc4ff1a-69b5-496b-a484-0aa99b886122",
"text": "Home",
"icon": "5bc4ff1a-69b5-496b-a484-0aa99b886122/1024x1024.png",
"page_type": "parent_menu",
"is_homepage": true,
"data": "5bc4ff1a-69b5-496b-a484-0aa99b886122",
"ui_config": "",
"order": 1,
"submenus": [
{
"id": "4960a54c-6d27-4d8d-a272-ebc7d9e8a55e",
"text": "Grid Menu",
"icon": "4960a54c-6d27-4d8d-a272-ebc7d9e8a55e/rose-3142529__340.jpg",
"page_type": "grid_menu",
"data": "4960a54c-6d27-4d8d-a272-ebc7d9e8a55e",
"ui_config": "",
"order": 1,
"submenus": [
{
"id": "906cd86f-df57-4175-a2c6-ca3a5c724e8a",
"text": "Article Page 2",
"icon": "906cd86f-df57-4175-a2c6-ca3a5c724e8a/rose-3142529__340.jpg",
"page_type": "article_page",
"data": "{\"page_id\":\"3e025c87-1d03-46a6-800e-0a9daea52bf4\"}",
"ui_config": "",
"order": 2
},
{
"id": "da8b054a-274e-4e1b-9d5a-e058a934838b",
"text": "Article Page",
"icon": "da8b054a-274e-4e1b-9d5a-e058a934838b/rose-3142529__340.jpg",
"page_type": "article_page",
"data": "{\"page_id\":\"3e025c87-1d03-46a6-800e-0a9daea52bf4\"}",
"ui_config": "",
"order": 1
}
]
}
]
}
]
Here lets say I need to get the object with id da8b054a-274e-4e1b-9d5a-e058a934838b. How do I do that?
Here is a recurisve function I wrote for this:
var currentMenuItem = null
function getTheCurrentMenu(menu, id) {
if (currentMenuItem != null) {
return
}
if (!Array.isArray(menu)) {
if (menu.id == id) {
currentMenuItem = menu
return
}
}
for (var item in menu) {
console.log(item)
getTheCurrentMenu(item, id)
}
}
This makes the browser unresponsive and shows error too much recursion.
Can someone please help me with this?
You could take an iterative and recursive call with a short circuit, if the item is found.
function find(array, id) {
var item;
for (item of array) {
if (item.id === id) return item;
if (item.submenus && (item = find(item.submenus, id))) return item;
}
}
var data = [{ id: "e1f015d3-4ca8-4dfd-839d-bed9bbbb82f8", text: "Parent Menu 2", icon: "e1f015d3-4ca8-4dfd-839d-bed9bbbb82f8/rose-3142529__340.jpg", page_type: "parent_menu", data: "e1f015d3-4ca8-4dfd-839d-bed9bbbb82f8", ui_config: "", order: 2 }, { id: "5bc4ff1a-69b5-496b-a484-0aa99b886122", text: "Home", icon: "5bc4ff1a-69b5-496b-a484-0aa99b886122/1024x1024.png", page_type: "parent_menu", is_homepage: true, data: "5bc4ff1a-69b5-496b-a484-0aa99b886122", ui_config: "", order: 1, submenus: [{ id: "4960a54c-6d27-4d8d-a272-ebc7d9e8a55e", text: "Grid Menu", icon: "4960a54c-6d27-4d8d-a272-ebc7d9e8a55e/rose-3142529__340.jpg", page_type: "grid_menu", data: "4960a54c-6d27-4d8d-a272-ebc7d9e8a55e", ui_config: "", order: 1, submenus: [{ id: "906cd86f-df57-4175-a2c6-ca3a5c724e8a", text: "Article Page 2", icon: "906cd86f-df57-4175-a2c6-ca3a5c724e8a/rose-3142529__340.jpg", page_type: "article_page", data: "{\"page_id\":\"3e025c87-1d03-46a6-800e-0a9daea52bf4\"}", ui_config: "", order: 2 }, { id: "da8b054a-274e-4e1b-9d5a-e058a934838b", text: "Article Page", icon: "da8b054a-274e-4e1b-9d5a-e058a934838b/rose-3142529__340.jpg", page_type: "article_page", data: "{\"page_id\":\"3e025c87-1d03-46a6-800e-0a9daea52bf4\"}", ui_config: "", order: 1 }] }] }],
id = 'da8b054a-274e-4e1b-9d5a-e058a934838b',
result = find(data, id);
console.log(result);
You can do this using reduce method and set accumulator to current element if id matches.
const data = [{"id":"e1f015d3-4ca8-4dfd-839d-bed9bbbb82f8","text":"Parent Menu 2","icon":"e1f015d3-4ca8-4dfd-839d-bed9bbbb82f8/rose-3142529__340.jpg","page_type":"parent_menu","data":"e1f015d3-4ca8-4dfd-839d-bed9bbbb82f8","ui_config":"","order":2},{"id":"5bc4ff1a-69b5-496b-a484-0aa99b886122","text":"Home","icon":"5bc4ff1a-69b5-496b-a484-0aa99b886122/1024x1024.png","page_type":"parent_menu","is_homepage":true,"data":"5bc4ff1a-69b5-496b-a484-0aa99b886122","ui_config":"","order":1,"submenus":[{"id":"4960a54c-6d27-4d8d-a272-ebc7d9e8a55e","text":"Grid Menu","icon":"4960a54c-6d27-4d8d-a272-ebc7d9e8a55e/rose-3142529__340.jpg","page_type":"grid_menu","data":"4960a54c-6d27-4d8d-a272-ebc7d9e8a55e","ui_config":"","order":1,"submenus":[{"id":"906cd86f-df57-4175-a2c6-ca3a5c724e8a","text":"Article Page 2","icon":"906cd86f-df57-4175-a2c6-ca3a5c724e8a/rose-3142529__340.jpg","page_type":"article_page","data":"{\"page_id\":\"3e025c87-1d03-46a6-800e-0a9daea52bf4\"}","ui_config":"","order":2},{"id":"da8b054a-274e-4e1b-9d5a-e058a934838b","text":"Article Page","icon":"da8b054a-274e-4e1b-9d5a-e058a934838b/rose-3142529__340.jpg","page_type":"article_page","data":"{\"page_id\":\"3e025c87-1d03-46a6-800e-0a9daea52bf4\"}","ui_config":"","order":1}]}]}]
function get(data, id) {
return data.reduce((r, e) => {
if(e.id === id) r = e;
if(!r && e.submenus) return get(e.submenus, id)
return r;
}, null)
}
const result = get(data, 'da8b054a-274e-4e1b-9d5a-e058a934838b');
console.log(result)
var data = `
[
{
"id": "e1f015d3-4ca8-4dfd-839d-bed9bbbb82f8",
"text": "Parent Menu 2",
"icon": "e1f015d3-4ca8-4dfd-839d-bed9bbbb82f8/rose-3142529__340.jpg",
"page_type": "parent_menu",
"data": "e1f015d3-4ca8-4dfd-839d-bed9bbbb82f8",
"ui_config": "",
"order": 2
},
{
"id": "5bc4ff1a-69b5-496b-a484-0aa99b886122",
"text": "Home",
"icon": "5bc4ff1a-69b5-496b-a484-0aa99b886122/1024x1024.png",
"page_type": "parent_menu",
"is_homepage": true,
"data": "5bc4ff1a-69b5-496b-a484-0aa99b886122",
"ui_config": "",
"order": 1,
"submenus": [
{
"id": "4960a54c-6d27-4d8d-a272-ebc7d9e8a55e",
"text": "Grid Menu",
"icon": "4960a54c-6d27-4d8d-a272-ebc7d9e8a55e/rose-3142529__340.jpg",
"page_type": "grid_menu",
"data": "4960a54c-6d27-4d8d-a272-ebc7d9e8a55e",
"ui_config": "",
"order": 1,
"submenus": [
{
"id": "906cd86f-df57-4175-a2c6-ca3a5c724e8a",
"text": "Article Page 2",
"icon": "906cd86f-df57-4175-a2c6-ca3a5c724e8a/rose-3142529__340.jpg",
"page_type": "article_page",
"ui_config": "",
"order": 2
},
{
"id": "da8b054a-274e-4e1b-9d5a-e058a934838b",
"text": "Article Page",
"icon": "da8b054a-274e-4e1b-9d5a-e058a934838b/rose-3142529__340.jpg",
"page_type": "article_page",
"ui_config": "",
"order": 1
}
]
}
]
}
]`;
var menu = JSON.parse(data);
async function getTheCurrentMenu(menu, id) {
if (!Array.isArray(menu)) {
if (menu.id == id) {
return menu;
} else if(menu.submenus){
return getTheCurrentMenu(menu.submenus, id);
} else {
return;
}
}
for (let item of menu) {
console.log(item)
let result = await getTheCurrentMenu(item, id);
if(result != null) {
return result;
}
}
}
getTheCurrentMenu(menu, 'da8b054a-274e-4e1b-9d5a-e058a934838b').then((item) => {
console.log("Result: ", item);
})
This question might be similar to frequently asked one, but this one has some different approach.
In my angular 7 application, I have the following 5 arrays which needs to be converted to the below single object with dynamic key based on the id.
{
"enabled-41": true,
"enabled-42": true,
"enabled-43": true,
"enabled-44": true,
"enabled-45": false,
"abc-41": "some description 1",
"abc-42": "some description 12",
"abc-43": "some description 123",
"abc-44": "some description 1234",
"abc-45": null,
"def-41": "some description 2",
"def-42": "some description 23",
"def-43": "some description 234",
"def-44": "some description 2345",
"def-45": null,
"type-41": "def",
"type-42": "abc",
"type-43": "def",
"type-44": "abc",
"type-45": null,
"weight-41": "25",
"weight-42": "25",
"weight-43": "25",
"weight-44": "25",
"weight-45": null
}
let arr = [
{
"id": 41,
"abc": "some description 1",
"def": "some description 2",
"type": "def",
"Criteria": {
"id": 5,
"question": "follow-up",
"definition": "definition content",
"status": true
},
"weight": 25,
"enabled": true
},
{
"id": 42,
"abc": "some description 12",
"def": "some description 23",
"type": "abc",
"Criteria": {
"id": 1,
"question": "coverage",
"definition": "definition content",
"status": true
},
"weight": 25,
"enabled": true
},
{
"id": 43,
"abc": "some description 123",
"def": "some description 234",
"type": "def",
"Criteria": {
"id": 4,
"question": "Price",
"definition": "definition content",
"status": true
},
"weight": 25,
"enabled": true
},
{
"id": 44,
"abc": "some description 1234",
"def": "some description 2345",
"type": "abc",
"Criteria": {
"id": 3,
"question": "Exchange",
"definition": "definition content",
"status": true
},
"weight": 25,
"enabled": true
},
{
"id": 45,
"Criteria": {
"id": 2,
"definition": "definition conent",
"question": "Random",
"status": true
},
"type": null,
"abc": null,
"def": null,
"weight": 0,
"enabled": false
}
];
let result = arr.reduce(function(obj, item) {
obj[item] = item.value;
return obj;
}, {})
console.log(result);
I have tried using reduce function, but cannot able to get the right way to convert to a single object with the above format based on dynamic key (joining id with hypen).
Can someone help me with this?
You can use reduce with Object.keys, and place all keys you wish to exclude in an array and check against that:
let arr = [{"id":41,"abc":"some description 1","def":"some description 2","type":"def","Criteria":{"id":5,"question":"follow-up","definition":"definition content","status":true},"weight":25,"enabled":true},{"id":42,"abc":"some description 12","def":"some description 23","type":"abc","Criteria":{"id":1,"question":"coverage","definition":"definition content","status":true},"weight":25,"enabled":true},{"id":43,"abc":"some description 123","def":"some description 234","type":"def","Criteria":{"id":4,"question":"Price","definition":"definition content","status":true},"weight":25,"enabled":true},{"id":44,"abc":"some description 1234","def":"some description 2345","type":"abc","Criteria":{"id":3,"question":"Exchange","definition":"definition content","status":true},"weight":25,"enabled":true},{"id":45,"Criteria":{"id":2,"definition":"definition conent","question":"Random","status":true},"type":null,"abc":null,"def":null,"weight":0,"enabled":false}];
let exclude = ["id", "Criteria"];
let result = arr.reduce((acc, curr) => {
let id = curr.id;
Object.entries(curr).forEach(([k, v]) => {
if (!exclude.includes(k)) acc[`${k}-${id}`] = v;
});
return acc;
}, {});
console.log(result);
You code is almost there. But object keys order is not guaranteed. Inside the reduce callback function add the keys in the accumulator and corresponding value.
Use template literals & square notation while creating the object keys
let arr = [{
"id": 41,
"abc": "some description 1",
"def": "some description 2",
"type": "def",
"Criteria": {
"id": 5,
"question": "follow-up",
"definition": "definition content",
"status": true
},
"weight": 25,
"enabled": true
},
{
"id": 42,
"abc": "some description 12",
"def": "some description 23",
"type": "abc",
"Criteria": {
"id": 1,
"question": "coverage",
"definition": "definition content",
"status": true
},
"weight": 25,
"enabled": true
},
{
"id": 43,
"abc": "some description 123",
"def": "some description 234",
"type": "def",
"Criteria": {
"id": 4,
"question": "Price",
"definition": "definition content",
"status": true
},
"weight": 25,
"enabled": true
},
{
"id": 44,
"abc": "some description 1234",
"def": "some description 2345",
"type": "abc",
"Criteria": {
"id": 3,
"question": "Exchange",
"definition": "definition content",
"status": true
},
"weight": 25,
"enabled": true
},
{
"id": 45,
"Criteria": {
"id": 2,
"definition": "definition conent",
"question": "Random",
"status": true
},
"type": null,
"abc": null,
"def": null,
"weight": 0,
"enabled": false
}
];
let result = arr.reduce(function(obj, item) {
obj[`enabled-${item.id}`] = item.enabled;
obj[`abc-${item.id}`] = item.abc;
obj[`def-${item.id}`] = item.def;
obj[`type-${item.id}`] = item.type;
obj[`weight-${item.id}`] = item.weight;
return obj;
}, {});
console.log(result)
Assuming you want to exclude all the properties whose value is an object maybe you can go with this generic idea that uses Object.entries() to traverse the inner objects and some destructuring features.
let arr=[{"id":41,"abc":"some description 1","def":"some description 2","type":"def","Criteria":{"id":5,"question":"follow-up","definition":"definition content","status":true},"weight":25,"enabled":true},{"id":42,"abc":"some description 12","def":"some description 23","type":"abc","Criteria":{"id":1,"question":"coverage","definition":"definition content","status":true},"weight":25,"enabled":true},{"id":43,"abc":"some description 123","def":"some description 234","type":"def","Criteria":{"id":4,"question":"Price","definition":"definition content","status":true},"weight":25,"enabled":true},{"id":44,"abc":"some description 1234","def":"some description 2345","type":"abc","Criteria":{"id":3,"question":"Exchange","definition":"definition content","status":true},"weight":25,"enabled":true},{"id":45,"Criteria":{"id":2,"definition":"definition conent","question":"Random","status":true},"type":null,"abc":null,"def":null,"weight":0,"enabled":false}];
let result = arr.reduce((obj, {id, ...rest}) =>
{
Object.entries(rest).forEach(([k, v]) =>
{
if (Object(v) !== v) obj[`${k}-${id}`] = v;
});
return obj;
}, {});
console.log(result);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}
Oh, man... I just got beat. Here's my solution.
let arr= [] // hold the final object array
let keys = [] // temp item to hold the value of each key
// iterate over each key
Object.keys(input).forEach((key) => {
let pair = key.split('-') // split the key into the real key and the index
// if the index isn't in the array, push it there (this keeps the same order)
if (keys.indexOf(pair[1])===-1) {
keys.push(pair[1])
}
// use object.assign to add the keys to the existing object in the right place in the array.
arr[keys.indexOf(pair[1])] = Object.assign({}, arr[keys.indexOf(pair[1])], {[pair[0]]: input[key]}, { id: pair[1] })
})
function getFilteredData(arr) {
const result = {};
arr.forEach(item => {
const { id, Criteria, ...rest } = item;
Object.entries(rest).map(([key, value]) => {
result[`${key}-${id}`] = value;
});
});
return result;
}
let arr = [
{
id: 41,
abc: 'some description 1',
def: 'some description 2',
type: 'def',
Criteria: {
id: 5,
question: 'follow-up',
definition: 'definition content',
status: true
},
weight: 25,
enabled: true
},
{
id: 42,
abc: 'some description 12',
def: 'some description 23',
type: 'abc',
Criteria: {
id: 1,
question: 'coverage',
definition: 'definition content',
status: true
},
weight: 25,
enabled: true
},
{
id: 43,
abc: 'some description 123',
def: 'some description 234',
type: 'def',
Criteria: {
id: 4,
question: 'Price',
definition: 'definition content',
status: true
},
weight: 25,
enabled: true
},
{
id: 44,
abc: 'some description 1234',
def: 'some description 2345',
type: 'abc',
Criteria: {
id: 3,
question: 'Exchange',
definition: 'definition content',
status: true
},
weight: 25,
enabled: true
},
{
id: 45,
Criteria: {
id: 2,
definition: 'definition conent',
question: 'Random',
status: true
},
type: null,
abc: null,
def: null,
weight: 0,
enabled: false
}
];
console.log(getFilteredData(arr));