简体   繁体   English

JavaScript递归函数可将父/子记录转换为嵌套数组

[英]JavaScript recursive function to transform parent/child records into a nested array

I have a Json array, which is structured perfectly for a Kendo treelist widget (ie very simple treelist example treelist ); 我有一个Json数组,它对于Kendo树列表小部件(即,非常简单的树列表示例treelist )的结构非常完美; however, I now need to render the same data in a Kendo treemap widget. 但是,我现在需要在Kendo树状图窗口小部件中渲染相同的数据。

So, the source data is flat and contains both an id and parentId field. 因此,源数据是平坦的,并且包含idparentId字段。 I now need to recursively visit each node and transform this into a nested array. 现在,我需要递归地访问每个节点,并将其转换为嵌套数组。

I've started a plunk which contains the flat source data (filename is "sourcedata.json"), as well as sample target data ("treedata.json") which currently renders a Kendo treemap if you run the plunk. 我已经启动了一个插件,其中包含平面源数据(文件名为“ sourcedata.json”),以及示例目标数据(“ treedata.json”),如果您运行该插件,当前该示例目标数据将呈现Kendo树状图。

 http://plnkr.co/edit/Cmfk8YWdm0uPrdDiJIfC?p=preview   

treemap data 树状图数据

Here's the source (fyi: "parentId": null is my root node) - 来源(fyi:“ parentId”:null是我的根节点)-

 [ { "id": 0, "parentId": 6, "typeId": 0, "field0": "London", "field2": 5546919.064936 }, { "id": 1, "parentId": 7, "typeId": 0, "field0": "New York", "field2": 2297941.24812 }, { "id": 2, "parentId": 5, "typeId": 0, "field0": "Dubai", "field2": 9832458.096596 }, { "id": 3, "parentId": 6, "typeId": 0, "field0": "Paris", "field2": 22700818.88167 }, { "id": 4, "parentId": 8, "typeId": 0, "field0": "Stockholm", "field2": 3742748.296602, }, { "id": 5, "parentId": 9, "typeId": 0, "field0": "Middle East", "field2": 9832458.096596, }, { "id": 6, "parentId": 9, "typeId": 0, "field0": "Europe", "field2": 31990486.243208, }, { "id": 7, "parentId": 9, "typeId": 0, "field0": "NorthAmerica", "field2": 2297941.24812, }, { "id": 8, "parentId": 6, "typeId": 0, "field0": "Scandinavia", "field2": 3742748.296602, }, { "id": 9, "parentId": null, "typeId": 0, "field0": "World", "field2": 44120885.587924, }, { "id": 10, "parentId": 0, "typeId": 1, "field0": "BOND-1001", "field2": 3985.331955, }, { "id": 28, "parentId": 0, "typeId": 1, "field0": "IRSW-08634", "field2": 10307.142591, }, { "id": 29, "parentId": 0, "typeId": 1, "field0": "IRSW-08639", "field2": 17116.371459, }, { "id": 58, "parentId": 0, "typeId": 1, "field0": "BOND-0013", "field2": 19029.816578, }, { "id": 59, "parentId": 0, "typeId": 1, "field0": "BOND-0031", "field2": -237.872707, }, { "id": 60, "parentId": 0, "typeId": 1, "field0": "BOND-0034", "field2": 859.61482, }, { "id": 61, "parentId": 0, "typeId": 1, "field0": "BOND-0037", "field2": 852.099758, }, { "id": 62, "parentId": 0, "typeId": 1, "field0": "BOND-0043", "field2": 4452.369428, "field4": 1 }, { "id": 63, "parentId": 0, "typeId": 1, "field0": "BOND-0046", "field2": -2226.184714, }, { "id": 64, "parentId": 0, "typeId": 1, "field0": "BOND-0049", "field2": 6612.946972, }, { "id": 65, "parentId": 0, "typeId": 1, "field0": "BOND-0050", "field2": 3844146.217229, }, { "id": 66, "parentId": 1, "typeId": 1, "field0": "BOND-1002", "field2": 3985.331955, }, { "id": 67, "parentId": 1, "typeId": 1, "field0": "BOND-1005", "field2": -2707.4266, }, { "id": 68, "parentId": 1, "typeId": 1, "field0": "BOND-1008", "field2": -2436.68394, }, { "id": 69, "parentId": 1, "typeId": 1, "field0": "BOND-1011", "field2": 683.959918, }, { "id": 70, "parentId": 1, "typeId": 1, "field0": "BOND-1014", "field2": 54716.79346, }, { "id": 71, "parentId": 1, "typeId": 1, "field0": "BOND-1017", "field2": 4027.155999, }, { "id": 72, "parentId": 1, "typeId": 1, "field0": "XCSW-0046", "field2": 604546.163294, "node2": 2, "field3": 498334.387729, "node3": 3, "field4": 1 }, { "id": 73, "parentId": 1, "typeId": 1, "field0": "IRSW-08655", "field2": 46191.801872, "node2": 2, "field3": 37131.473418, "node3": 3, "field4": 1 }, { "id": 74, "parentId": 1, "typeId": 1, "field0": "CF-0012", "field2": 1845434.652127, "node2": 2, "field3": 1438283.786114, "node3": 3, "field4": 1 }, { "id": 75, "parentId": 1, "typeId": 1, "field0": "CF-0017", "field2": 46486.869315, "node2": 2, "field3": 36285.674082, "node3": 3, "field4": 1 }, { "id": 76, "parentId": 1, "typeId": 1, "field0": "CF-0002", "field2": -593582.845166, "node2": 2, "field3": -402546.0446, "node3": 3, "field4": 1 }, { "id": 77, "parentId": 1, "typeId": 1, "field0": "CRSW-1002", "field2": -73496.275293, "node2": 2, "field3": -5325.413593, "node3": 3, "field4": 1 }, { "id": 78, "parentId": 1, "typeId": 1, "field0": "CRSW-1005", "field2": 20670.748989, "node2": 2, "field3": 27954.103116, "node3": 3, "field4": 1 }, { "id": 79, "parentId": 1, "typeId": 1, "field0": "CRSW-1008", "field2": 53572.838484, "node2": 2, "field3": 27688.010937, "node3": 3, "field4": 1 }, { "id": 80, "parentId": 1, "typeId": 1, "field0": "CRSW-1011", "field2": 58.44961, "node2": 2, "field3": 83.488679, "node3": 3, "field4": 1 }, { "id": 81, "parentId": 1, "typeId": 1, "field0": "CRSW-1014", "field2": -296158.053382, "node2": 2, "field3": -288493.393334, "node3": 3, "field4": 1 }, { "id": 82, "parentId": 1, "typeId": 1, "field0": "CRSW-1017", "field2": -21563.217578, "node2": 2, "field3": -20779.990677, "node3": 3, "field4": 1 }, { "id": 83, "parentId": 1, "typeId": 1, "field0": "LOAN-0012", "field2": -16809.368436, "node2": 2, "field3": -16401.910829, "node3": 3, "field4": 1 }, { "id": 84, "parentId": 1, "typeId": 1, "field0": "LOAN-0017", "field2": 10307.142591, "node2": 2, "field3": 9867.818502, "node3": 3, "field4": 1 }, { "id": 85, "parentId": 1, "typeId": 1, "field0": "FX-00342", "field2": 17116.371459, "node2": 2, "field3": 16382.149866, "node3": 3, "field4": 1 }, { "id": 86, "parentId": 1, "typeId": 1, "field0": "FX-00354", "field2": 3721.762854, "node2": 2, "field3": 3541.481944, "node3": 3, "field4": 1 }, { "id": 87, "parentId": 1, "typeId": 1, "field0": "FX-00406", "field2": 1479.737038, "node2": 2, "field3": 1408.059086, "node3": 3, "field4": 1 }, { "id": 88, "parentId": 1, "typeId": 1, "field0": "FX-00410", "field2": 4699.141795, "node2": 2, "field3": 4487.080289, "node3": 3, "field4": 1 }, { "id": 89, "parentId": 1, "typeId": 1, "field0": "FX-00418", "field2": 53.411383, "node2": 2, "field3": -25.478062, "node3": 3, "field4": 1 }, { "id": 90, "parentId": 1, "typeId": 1, "field0": "FX-00426", "field2": 1625.14897, "node2": 2, "field3": 2319.189521, "node3": 3, "field4": 1 }, { "id": 91, "parentId": 1, "typeId": 1, "field0": "FRA-0002", "field2": -4634.930756, "node2": 2, "field3": -6613.572492, "node3": 3, "field4": 1 }, { "id": 92, "parentId": 1, "typeId": 1, "field0": "FRA-0005", "field2": -7375.479672, "node2": 2, "field3": -17104.920999, "node3": 3, "field4": 1 }, { "id": 93, "parentId": 1, "typeId": 1, "field0": "FRA-0008", "field2": 0, "node2": 2, "field3": 0, "node3": 3, "field4": 1 }, { "id": 94, "parentId": 1, "typeId": 1, "field0": "FRA-0011", "field2": 125.281197, "node2": 2, "field3": 181.176247, "node3": 3, "field4": 1 }, { "id": 95, "parentId": 1, "typeId": 1, "field0": "FRA-0014", "field2": 95.900079, "node2": 2, "field3": 122.515322, "node3": 3, "field4": 1 }, { "id": 96, "parentId": 1, "typeId": 1, "field0": "BOND-0014", "field2": 35.094497, "node2": 2, "field3": 45.048084, "node3": 3, "field4": 1 }, { "id": 97, "parentId": 1, "typeId": 1, "field0": "BOND-0017", "field2": 42.085388, "node2": 2, "field3": 61.758662, "node3": 3, "field4": 1 }, { "id": 98, "parentId": 1, "typeId": 1, "field0": "BOND-0023", "field2": -1527.85633, "node2": 2, "field3": -7451.691034, "node3": 3, "field4": 1 }, { "id": 99, "parentId": 1, "typeId": 1, "field0": "BOND-0029", "field2": -10505.835091, "node2": 2, "field3": -43600.76525, "node3": 3, "field4": 1 }, { "id": 100, "parentId": 1, "typeId": 1, "field0": "BOND-0032", "field2": 0, "node2": 2, "field3": 0, "node3": 3, "field4": 1 }, { "id": 101, "parentId": 1, "typeId": 1, "field0": "BOND-0035", "field2": 8.385045, "node2": 2, "field3": 2967.079788, "node3": 3, "field4": 1 }, { "id": 102, "parentId": 1, "typeId": 1, "field0": "BOND-0041", "field2": 543.371559, "node2": 2, "field3": 29891.343594, "node3": 3, "field4": 1 }, { "id": 103, "parentId": 1, "typeId": 1, "field0": "BOND-0044", "field2": 73.610827, "node2": 2, "field3": 5960.758206, "node3": 3, "field4": 1 }, { "id": 104, "parentId": 1, "typeId": 1, "field0": "BOND-0047", "field2": 894.247491, "node2": 2, "field3": 15292.150889, "node3": 3, "field4": 1 }, { "id": 105, "parentId": 2, "typeId": 1, "field0": "BOND-1003", "field2": 3985.331955, "node2": 2, "field3": 20567.245997, "node3": 3, "field4": 1 }, { "id": 106, "parentId": 2, "typeId": 1, "field0": "BOND-1006", "field2": -2707.4266, "node2": 2, "field3": -13972.313856, "node3": 3, "field4": 1 }, { "id": 107, "parentId": 2, "typeId": 1, "field0": "BOND-1009", "field2": -2436.68394, "node2": 2, "field3": -12575.082471, "node3": 3, "field4": 1 }, { "id": 108, "parentId": 2, "typeId": 1, "field0": "BOND-1012", "field2": 683.959918, "node2": 2, "field3": 3527.163486, "node3": 3, "field4": 1 }, { "id": 109, "parentId": 2, "typeId": 1, "field0": "BOND-1015", "field2": 54716.79346, "node2": 2, "field3": 282173.078874, "node3": 3, "field4": 1 }, { "id": 110, "parentId": 2, "typeId": 1, "field0": "XCSW-0004", "field2": 4027.155999, "node2": 2, "field3": 20767.938605, "node3": 3, "field4": 1 }, { "id": 111, "parentId": 2, "typeId": 1, "field0": "XCSW-0014", "field2": 604546.163294, "node2": 2, "field3": 498334.387729, "node3": 3, "field4": 1 }, { "id": 112, "parentId": 2, "typeId": 1, "field0": "XCSW-0017", "field2": 46191.801872, "node2": 2, "field3": 37131.473418, "node3": 3, "field4": 1 }, { "id": 113, "parentId": 2, "typeId": 1, "field0": "XCSW-0029", "field2": 1845434.652127, "node2": 2, "field3": 1438283.786114, "node3": 3, "field4": 1 }, { "id": 114, "parentId": 2, "typeId": 1, "field0": "XCSW-0034", "field2": 46486.869315, "node2": 2, "field3": 36285.674082, "node3": 3, "field4": 1 }, { "id": 115, "parentId": 2, "typeId": 1, "field0": "XCSW-0045", "field2": -593582.845166, "node2": 2, "field3": -402546.0446, "node3": 3, "field4": 1 }, { "id": 116, "parentId": 2, "typeId": 1, "field0": "XCSW-0053", "field2": -73496.275293, "node2": 2, "field3": -5325.413593, "node3": 3, "field4": 1 }, { "id": 117, "parentId": 2, "typeId": 1, "field0": "XCSW-0072", "field2": 20670.748989, "node2": 2, "field3": 27954.103116, "node3": 3, "field4": 1 }, { "id": 118, "parentId": 2, "typeId": 1, "field0": "IRSW-00022", "field2": 53572.838484, "node2": 2, "field3": 27688.010937, "node3": 3, "field4": 1 }, { "id": 119, "parentId": 2, "typeId": 1, "field0": "IRSW-00030", "field2": 58.44961, "node2": 2, "field3": 83.488679, "node3": 3, "field4": 1 }, { "id": 120, "parentId": 2, "typeId": 1, "field0": "IRSW-00037", "field2": -296158.053382, "node2": 2, "field3": -288493.393334, "node3": 3, "field4": 1 }, { "id": 121, "parentId": 2, "typeId": 1, "field0": "IRSW-00042", "field2": -21563.217578, "node2": 2, "field3": -20779.990677, "node3": 3, "field4": 1 }, { "id": 122, "parentId": 2, "typeId": 1, "field0": "IRSW-04172", "field2": -16809.368436, "node2": 2, "field3": -16401.910829, "node3": 3, "field4": 1 }, { "id": 123, "parentId": 2, "typeId": 1, "field0": "IRSW-04177", "field2": 10307.142591, "node2": 2, "field3": 9867.818502, "node3": 3, "field4": 1 }, { "id": 124, "parentId": 2, "typeId": 1, "field0": "IRSW-04182", "field2": 17116.371459, "node2": 2, "field3": 16382.149866, "node3": 3, "field4": 1 }, { "id": 125, "parentId": 2, "typeId": 1, "field0": "IRSW-04185", "field2": 3721.762854, "node2": 2, "field3": 3541.481944, "node3": 3, "field4": 1 }, { "id": 126, "parentId": 2, "typeId": 1, "field0": "IRSW-04192", "field2": 1479.737038, "node2": 2, "field3": 1408.059086, "node3": 3, "field4": 1 }, { "id": 127, "parentId": 2, "typeId": 1, "field0": "IRSW-08627", "field2": 4699.141795, "node2": 2, "field3": 4487.080289, "node3": 3, "field4": 1 }, { "id": 128, "parentId": 2, "typeId": 1, "field0": "IRSW-08632", "field2": 53.411383, "node2": 2, "field3": -25.478062, "node3": 3, "field4": 1 }, { "id": 129, "parentId": 2, "typeId": 1, "field0": "IRSW-08637", "field2": 1625.14897, "node2": 2, "field3": 2319.189521, "node3": 3, "field4": 1 }, { "id": 130, "parentId": 2, "typeId": 1, "field0": "IRSW-08642", "field2": -4634.930756, "node2": 2, "field3": -6613.572492, "node3": 3, "field4": 1 }, { "id": 131, "parentId": 2, "typeId": 1, "field0": "IRSW-08647", "field2": -7375.479672, "node2": 2, "field3": -17104.920999, "node3": 3, "field4": 1 }, { "id": 132, "parentId": 2, "typeId": 1, "field0": "IRSW-08650", "field2": 0, "node2": 2, "field3": 0, "node3": 3, "field4": 1 }, { "id": 133, "parentId": 2, "typeId": 1, "field0": "IRSW-08652", "field2": 125.281197, "node2": 2, "field3": 181.176247, "node3": 3, "field4": 1 }, { "id": 134, "parentId": 2, "typeId": 1, "field0": "IRSW-08657", "field2": 95.900079, "node2": 2, "field3": 122.515322, "node3": 3, "field4": 1 }, { "id": 135, "parentId": 2, "typeId": 1, "field0": "CF-0004", "field2": 35.094497, "node2": 2, "field3": 45.048084, "node3": 3, "field4": 1 }, { "id": 136, "parentId": 2, "typeId": 1, "field0": "CF-0014", "field2": 42.085388, "node2": 2, "field3": 61.758662, "node3": 3, "field4": 1 }, { "id": 137, "parentId": 2, "typeId": 1, "field0": "CF-0024", "field2": -1527.85633, "node2": 2, "field3": -7451.691034, "node3": 3, "field4": 1 }, { "id": 138, "parentId": 2, "typeId": 1, "field0": "CF-0029", "field2": -10505.835091, "node2": 2, "field3": -43600.76525, "node3": 3, "field4": 1 }, { "id": 139, "parentId": 2, "typeId": 1, "field0": "CF-0009", "field2": 0, "node2": 2, "field3": 0, "node3": 3, "field4": 1 }, { "id": 140, "parentId": 2, "typeId": 1, "field0": "CRSW-1003", "field2": 8.385045, "node2": 2, "field3": 2967.079788, "node3": 3, "field4": 1 }, { "id": 141, "parentId": 2, "typeId": 1, "field0": "CRSW-1006", "field2": 543.371559, "node2": 2, "field3": 29891.343594, "node3": 3, "field4": 1 }, { "id": 142, "parentId": 2, "typeId": 1, "field0": "CRSW-1009", "field2": 73.610827, "node2": 2, "field3": 5960.758206, "node3": 3, "field4": 1 }, { "id": 143, "parentId": 2, "typeId": 1, "field0": "CRSW-1012", "field2": 894.247491, "node2": 2, "field3": 15292.150889, "node3": 3, "field4": 1 }, { "id": 144, "parentId": 2, "typeId": 1, "field0": "CRSW-1015", "field2": 1788.494983, "node2": 2, "field3": 30584.301778, "node3": 3, "field4": 1 }, { "id": 145, "parentId": 2, "typeId": 1, "field0": "LOAN-0004", "field2": 1788.494983, "node2": 2, "field3": 30584.301778, "node3": 3, "field4": 1 }, { "id": 146, "parentId": 2, "typeId": 1, "field0": "LOAN-0014", "field2": -1346.424043, "node2": 2, "field3": 2340.573474, "node3": 3, "field4": 1 }, { "id": 147, "parentId": 2, "typeId": 1, "field0": "LOAN-0029", "field2": -1349.527119, "node2": 2, "field3": 2335.6426, "node3": 3, "field4": 1 }, { "id": 148, "parentId": 2, "typeId": 1, "field0": "CSA-3-1", "field2": 16116.217709, "node2": 2, "field3": 6028.837728, "node3": 3, "field4": 1 }, { "id": 149, "parentId": 2, "typeId": 1, "field0": "CSA-5-1", "field2": -144675.967051, "node2": 2, "field3": -52043.568419, "node3": 3, "field4": 1 }, { "id": 150, "parentId": 2, "typeId": 1, "field0": "CSA-10-1", "field2": 302407.68631, "node2": 2, "field3": 109564.416581, "node3": 3, "field4": 1 }, { "id": 151, "parentId": 2, "typeId": 1, "field0": "CSA-101-1", "field2": -189203.37048, "node2": 2, "field3": -69223.41632, "node3": 3, "field4": 1 }, { "id": 152, "parentId": 2, "typeId": 1, "field0": "CSA-4-1", "field2": -955.127578, "node2": 2, "field3": -898.382846, "node3": 3, "field4": 1 }, { "id": 230, "parentId": 4, "typeId": 1, "field0": "LOAN-0030", "field2": 4699.141795 } ] 

and the target data needs to have this nested array structure: 并且目标数据需要具有此嵌套数组结构:

 [ { "name": "HSVaR 1D 99%, By Location", "value":44120885.587924, "items":[ { "name":"NorthAmerica", "value": 2297941.24812, "items":[ { "name":"New York", "value":2297941.24812 } ] }, { "name":"Europe", "value":31990486.243208, "items":[ { "name":"London", "value":5546919.06 }, { "name":"Paris", "value":22700818.88167 }, { "name":"Scandinavia", "value":3742748.296602 } ] }, { "name":"Middle East", "value":2959373, "items":[ { "name":"Dubai", "value":9832458.096596 } ] } ] } ] 

* UPDATE: FINAL WORKING VERSION - Same nested results as the gentleman who answered below with a non-recursive routine * *更新:最终工作版本-与下面以非递归例程回答的绅士相同的嵌套结果*

 function parseTreeMapData(data) { // init new array, find root node var newJson = []; var root = _.findWhere(data, { parentId: null }); // recurse data, starting with root node; pass in empty array newJson = recurseTreeMapData(data, root, []); var top = []; top.push({ root.field0, value: root.field2, items: newJson.items }); return top; } function recurseTreeMapData(data, root, newData) { // passing in the root node, get children, recurse until leaf is reached. var child = _.where(data, { parentId: root.id }); if (child.length > 0) { if (!newData.items){ newData.items = []; } for (var i = 0; i < child.length; i++){ newData.items.push( { id: child[i].id, parentId: child[i].parentId, name: child[i].field0, value: child[i].field2 }); // recursve with current child record recurseTreeMapData(data, child[i], newData.items[i]); } } return newData; } 

Thank you in advance, 先感谢您,

Bob 短发

I've edited your plunk and I think I've got the data right here although the treemap doesn't look right. 我已经编辑了您的文件,尽管树形图看起来不正确但我想这里已经有数据了。

The algorithm I used was to first create a map from data IDs to data elements in the new format. 我使用的算法是先创建一个从数据ID到新格式的数据元素的映射。 Then I walk through the data again and add each data element to its parent's items array. 然后,我再次遍历数据并将每个数据元素添加到其父itemsitems数组中。 Since these are all references we're mutating things in place and there's no need for topological sorting or anything. 由于这些都是参考,因此我们可以对事物进行变异,并且不需要进行拓扑排序或其他任何操作。

I didn't find the need for recursion. 我没有发现需要递归。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM