Javascript 从node.js中的平面数组构建树数组

Javascript 从node.js中的平面数组构建树数组,javascript,arrays,json,node.js,npm,Javascript,Arrays,Json,Node.js,Npm,我有一个平面数组,我想在node.js中构建一个树数组。 我拥有的阵列如下所示: var data= [ { "id1": 1001, "id2": 1002, "id3": 1004, "id4": 1007, "id5": 1013, "id6": 1030, "id7": null,

我有一个平面数组,我想在node.js中构建一个树数组。 我拥有的阵列如下所示:

var data=  [
        {
            "id1": 1001,
            "id2": 1002,
            "id3": 1004,
            "id4": 1007,
            "id5": 1013,
            "id6": 1030,
            "id7": null,
            "id8": null,
            "id9": null,
            "accountid": 1108,
            "name1": "Net Income",
            "name2": "Net Income Before Extraordinary Item",
            "name3": "Income (Loss) from operations                     ",
            "name4": "Net Patient Revenue",
            "name5": "Gross Patient Revenue",
            "name6": "Inpatient Routine Services",
            "name7": null,
            "name8": null,
            "name9": null,
            "accountname": "3000000 - INPATIENT REVENUE                       ",
            "amt1": 6266235,
            "amt2": 0,
            "amt3": 7085312,
            "amt4": 7010901,
            "amt5": 7008743,
            "amt6": 6865373,
            "amt7": 7298176,
            "amt8": 7481711,
            "nCurMnth": 0,
            "samt4": 7010901,
            "id": 1030,
            "parentid": 1013,
            "relativelevel": 6,
            "accountdetailid": null,
            "variancecalc": 1,
            "InfoSetID": 1108,
            "InfoSetName": "3000000 - INPATIENT REVENUE                       ",
            "DetailType": "",
            "DecimalCount": 2
        },
        {
            "id1": 1001,
            "id2": 1002,
            "id3": 1004,
            "id4": 1007,
            "id5": 1013,
            "id6": 1030,
            "id7": null,
            "id8": null,
            "id9": null,
            "accountid": 2708,
            "name1": "Net Income",
            "name2": "Net Income Before Extraordinary Item",
            "name3": "Income (Loss) from operations                     ",
            "name4": "Net Patient Revenue",
            "name5": "Gross Patient Revenue",
            "name6": "Inpatient Routine Services",
            "name7": null,
            "name8": null,
            "name9": null,
            "accountname": "3000090 - INPATIENT SWING BED                     ",
            "amt1": 190887,
            "amt2": 0,
            "amt3": 256581,
            "amt4": 271789,
            "amt5": 235998,
            "amt6": 251224,
            "amt7": 307154,
            "amt8": 314971,
            "nCurMnth": 0,
            "samt4": 271789,
            "id": 1030,
            "parentid": 1013,
            "relativelevel": 6,
            "accountdetailid": null,
            "variancecalc": 1,
            "InfoSetID": 2708,
            "InfoSetName": "3000090 - INPATIENT SWING BED                     ",
            "DetailType": "",
            "DecimalCount": 2
        },
        {
            "id1": 1001,
            "id2": 1002,
            "id3": 1004,
            "id4": 1007,
            "id5": 1013,
            "id6": 1030,
            "id7": null,
            "id8": null,
            "id9": null,
            "accountid": 1114,
            "name1": "Net Income",
            "name2": "Net Income Before Extraordinary Item",
            "name3": "Income (Loss) from operations                     ",
            "name4": "Net Patient Revenue",
            "name5": "Gross Patient Revenue",
            "name6": "Inpatient Routine Services",
            "name7": null,
            "name8": null,
            "name9": null,
            "accountname": "3999000 - SUSPENSE DAILY REV CLEAR ACCT           ",
            "amt1": 0,
            "amt2": 0,
            "amt3": 0,
            "amt4": 0,
            "amt5": 0,
            "amt6": 0,
            "amt7": 0,
            "amt8": 0,
            "nCurMnth": 0,
            "samt4": 0,
            "id": 1030,
            "parentid": 1013,
            "relativelevel": 6,
            "accountdetailid": null,
            "variancecalc": 1,
            "InfoSetID": 1114,
            "InfoSetName": "3999000 - SUSPENSE DAILY REV CLEAR ACCT           ",
            "DetailType": "",
            "DecimalCount": 2
        },
        {
            "id1": 1001,
            "id2": 1002,
            "id3": 1004,
            "id4": 1007,
            "id5": 1013,
            "id6": 1031,
            "id7": null,
            "id8": null,
            "id9": null,
            "accountid": 1133,
            "name1": "Net Income",
            "name2": "Net Income Before Extraordinary Item",
            "name3": "Income (Loss) from operations                     ",
            "name4": "Net Patient Revenue",
            "name5": "Gross Patient Revenue",
            "name6": "Inpatient Ancillary Services",
            "name7": null,
            "name8": null,
            "name9": null,
            "accountname": "3070000 - INTERP - INP                            ",
            "amt1": 36886,
            "amt2": 0,
            "amt3": 47968,
            "amt4": 45109,
            "amt5": 38047,
            "amt6": 39158,
            "amt7": 31290,
            "amt8": 45148,
            "nCurMnth": 0,
            "samt4": 45109,
            "id": 1031,
            "parentid": 1013,
            "relativelevel": 6,
            "accountdetailid": null,
            "variancecalc": 1,
            "InfoSetID": 1133,
            "InfoSetName": "3070000 - INTERP - INP                            ",
            "DetailType": "",
            "DecimalCount": 2
        },
        {
            "id1": 1001,
            "id2": 1002,
            "id3": 1004,
            "id4": 1007,
            "id5": 1013,
            "id6": 1031,
            "id7": null,
            "id8": null,
            "id9": null,
            "accountid": 1135,
            "name1": "Net Income",
            "name2": "Net Income Before Extraordinary Item",
            "name3": "Income (Loss) from operations                     ",
            "name4": "Net Patient Revenue",
            "name5": "Gross Patient Revenue",
            "name6": "Inpatient Ancillary Services",
            "name7": null,
            "name8": null,
            "name9": null,
            "accountname": "3100000 - INPATIENT ANCILLARY REV                 ",
            "amt1": 18822593,
            "amt2": 0,
            "amt3": 21676463,
            "amt4": 21368866,
            "amt5": 20284449,
            "amt6": 21344632,
            "amt7": 20272660,
            "amt8": 21169123,
            "nCurMnth": 0,
            "samt4": 21368866,
            "id": 1031,
            "parentid": 1013,
            "relativelevel": 6,
            "accountdetailid": null,
            "variancecalc": 1,
            "InfoSetID": 1135,
            "InfoSetName": "3100000 - INPATIENT ANCILLARY REV                 ",
            "DetailType": "",
            "DecimalCount": 2
        },
        {
            "id1": 1001,
            "id2": 1002,
            "id3": 1004,
            "id4": 1007,
            "id5": 1013,
            "id6": 1031,
            "id7": null,
            "id8": null,
            "id9": null,
            "accountid": 1273,
            "name1": "Net Income",
            "name2": "Net Income Before Extraordinary Item",
            "name3": "Income (Loss) from operations                     ",
            "name4": "Net Patient Revenue",
            "name5": "Gross Patient Revenue",
            "name6": "Inpatient Ancillary Services",
            "name7": null,
            "name8": null,
            "name9": null,
            "accountname": "3100090 - SWING BED INPATIENT REV                 ",
            "amt1": 166993,
            "amt2": 0,
            "amt3": 225651,
            "amt4": 228349,
            "amt5": 143726,
            "amt6": 227736,
            "amt7": 235705,
            "amt8": 206381,
            "nCurMnth": 0,
            "samt4": 228349,
            "id": 1031,
            "parentid": 1013,
            "relativelevel": 6,
            "accountdetailid": null,
            "variancecalc": 1,
            "InfoSetID": 1273,
            "InfoSetName": "3100090 - SWING BED INPATIENT REV                 ",
            "DetailType": "",
            "DecimalCount": 2
        }
    ]
注意:-id1是根,其名称由name1表示,id2是id1的直接子级,其名称为name2,类似地,id3是id2的直接子级,其名称为name3,依此类推

现在,我想要一个由node.js中的名称表示的分层(树状)结构

我还想知道是否有任何包可以做到这一点

提前谢谢

树状结构的预期输出如下所示:

Net Income
   |
   ---------Net Income Before Extraordinary Item
            |
            ------Income (Loss) from operations
            |     |
            |     ------Net Patient Revenue   
            |           |
            |            --------- 
            ------XYZ

我不知道是否有一个包,另一方面,它似乎可以很容易地解决旅行的名称(直接因为他们匹配的id的)。这将按照
relativel
所说的缩进条目,将它们放入每个对象的属性
entry

// Configuration
var max_attrs = 9; // Max attrs (ex: name1 .. name9).
var ename = 'entry'; // Name of the entry.

var output = {};

function process_item(item) {
    // Dig into output
    var dig_n = item.relativelevel;
    var dig = output;
    while (--dig_n) {
        if (!(ename in dig))
            dig[ename] = {};
        dig = dig[ename];
    }

    // Generate entry
    var i = max_attrs;
    var entry;

    while (--i) {
        var name = item["name" + i];
        if (name) {
            if (!entry)
                entry = name;
            else {
                var entry_add = {};
                entry_add[name] = entry;
                entry = entry_add;
            }
        }
    };

    dig[ename] = entry  
}

data.forEach(function(item) {
    process_item(item);
})

// tree will be in variable output
console.log(JSON.stringify(output))

好的,对于这个好问题,我有一个可靠的答案。但在我讨论解决方案细节之前,这里是故事部分

实际上,这个问题解决了现代JS编程中一个非常常见的问题,即动态获取和设置嵌套值。我开发了两种对象方法,以功能方式满足这一需求。它们被称为
Object.prototype.getNestedValue()
Object.prototype.setNestedValue()
,它们都用于动态获取和设置对象以及数组属性和值

getNestedValue([prop1[,prop2[,prop3…]])将返回嵌套属性的值。你可以像这样调用它

`myObj.getNestedValue(a,"prop2",1);`
其中,
myObj
是调用它的对象,
a
是一个动态变量(如果字符串类型表示对象属性,但如果它是数字类型,则它是数组索引值),“prop2”是一个静态属性参数,最后一个1是数组的索引。当然,所有提供的参数都可以是动态的。如果数组中有参数,可以像调用
getNestedValue(…[a,b,c,d])那样调用它

setNestedValue([prop1[,prop2[,prop3…]],value)的工作原理与twin完全相同,但最后一个参数是要设置的值。如果属性不存在,它将根据所提供参数的类型创建一个对象或数组。同样,字符串类型参数将生成对象,而数字类型参数将生成该大小的数组

因此,正如你们将看到的,一旦我们手中有了这些工具,这个问题所涉及的问题就不再是问题了。让我们看看代码

Object.prototype.getNestedValue=函数(…a){
返回a.length>1?(this[a[0]!==void 0和this[a[0]]。getNestedValue(…a.slice(1)):this[a[0]];
};
Object.prototype.setNestedValue=函数(…a){
a、 长度>2?此[a[0]]的类型==“对象”&此[a[0]!==null?此[a[0]]。setNestedValue(…a.slice(1))
:(此[a[0]]=a[1]==“字符串”?{}:新数组(a[1]),的类型,
此[a[0]].setNestedValue(…a.slice(1)))
:此[a[0]]=a[1];
归还这个;
};
var dataStr='[{“id1”:1001,“id2”:1002,“id3”:1004,“id4”:1007,“id5”:1013,“id6”:1030,“id7”:null,“id8”:null,“id9”:null,“accountid”:1108,“name1:“净收入”,“name2:“特殊项目前净收入”,“name3:“手术收入(损失)”,“name4:“净患者收入”,“name5:“患者总收入”,“name6:”“住院患者常规服务”,“名称7”:null,“名称8”:null,“名称9”:null,“账户名称”:“3000000-住院患者收入”,“amt1”:6266235,“amt2”:0,“amt3”:7085312,“amt4”:7010901,“amt5”:7008743,“amt6”:6865373,“amt7”:7298176,“amt8”:7481711,“nCurMnth”:0,“samt4”:7010901,“id”:1030,“parentid”:1013,“Relativel”:6,“accountdetailid”:null,”variancecalc“:1,“InfoSetID”:1108,“InfoSetName:”3000000-住院患者收入“,”DetailType“,”DecimalCount“:2},{“id1”:1001,“id2”:1002,“id3”:1004,“id4”:1007,“id5”:1013,“id6”:1030,“id7”:null,“id8”:null,“id9”:null,“accountid”:2708,“name1:”净收入“,”name2:“name2:”非常项目前的净收入“,”name3:“收入(亏损)”来自运营部,“名称4”:“净患者收入”,“名称5”:“总患者收入”,“名称6”:“住院常规服务”,“名称7”:空,“名称8”:空,“名称9”:空,“账户名称”:“3000090-住院摇摆床”,“amt1”:190887,“amt2”:0,“amt3”:256581,“amt4”:271789,“amt5”:235998,“amt6”:251224,“amt7”:307154,“amt8”“:314971,“nCurMnth”:0,“samt4”:271789,“id”:1030,“parentid”:1013,“relativelevel”:6,“accountdetailid”:null,“variancecalc”:1,“InfoSetID”:2708,“InfoSetName”:“3000090-住院病人摇摆床”,“DetailType”:““小数点计数”:2},{“id1”:1001,“id2”:1002,“id3”:1004,“id4”:1007,“id5”:1013,“id6”:1030,“id7”:null,“id8”:null,“id9”:null,“accountid”:1114,“名称1”:“净收入”,“名称2”:“非经常项目前净收入”,“名称3”:“手术收入(损失)”,“名称4”:“净患者收入”,“名称5”:“患者总收入”,“名称6”:“住院常规服务”,“名称7”:null,“名称8”:null,“名称9”:null,“账户名称”:“3999000-暂记每日修订结算账户”,“amt1”:0,“amt2”:0,“amt3”:0,“amt4”:0,“amt5”:0,“amt6”:0,“amt7”:0,“amt8”:0,“nCurMnth”:0,“samt4”:0,“id”:1030,“parentid”:1013,“relativelevel”:6,“accountdetailid”:null,“variancecalc”:1,“InfoSetID”:1114,“InfoSetName”:“3999000-暂记每日修订结算账户”,“DetailType”:“,“DecimalCount”:2},{“id1”:1002,“id3”:1004,“id4”:1007,“ID1015”:id6“:1031,“id7”:null,“id8”:null,“id9”:null,“accountid”:1133,“name1”:“净收入”,“name2”:“非经常项目前净收入”,“name3”:“手术收入(损失)”,“name4”:“患者净收入”,“name5”:“患者总收入”,“name6”:“住院辅助服务”,“name7”:null,“name8”:null,“name9”:null,”accountname”:“3070000-INTP-INP”,“amt1”:36886,“amt2”:0,“am”