Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 将平面数组转换为嵌套数组_Javascript_Arrays_Tree - Fatal编程技术网

Javascript 将平面数组转换为嵌套数组

Javascript 将平面数组转换为嵌套数组,javascript,arrays,tree,Javascript,Arrays,Tree,我有一个javascript对象数组,如下所示: // Id is not necessarily unique, orderly or for any specific purpose var input = [ { Id: 1, LongName: "Europe;Germany;Frankfurt", Attribute1: "some attribute" }, { Id: 2, LongName: "Europe;Ger

我有一个javascript对象数组,如下所示:

// Id is not necessarily unique, orderly or for any specific purpose
var input = [
    { Id: 1, LongName: "Europe;Germany;Frankfurt", Attribute1: "some attribute" },
    { Id: 2, LongName: "Europe;Germany;Munich", Attribute1: "some attribute" },
    { Id: 7, LongName: "Asia;Japan;Okinawa", Attribute1: "some attribute" },
    { Id: 8, LongName: "North America;US;Seattle", Attribute1: "some attribute" },
    { Id: 10, LongName: "Asia;China;Beijing", Attribute1: "some attribute" },
    { Id: 12, LongName: "Europe;France;Paris", Attribute1: "some attribute" },
    { Id: 14, LongName: "Europe;France;Marseille", Attribute1: "some attribute" },
    { Id: 5, LongName: "Asia;Japan;Tokyo", Attribute1: "some attribute" },
    { Id: 6, LongName: "Asia;Korea;Seoul", Attribute1: "some attribute" },
    { Id: 9, LongName: "Asia;Korea;Busan", Attribute1: "some attribute" },
    { Id: 11, LongName: "North America;US;New York", Attribute1: "some attribute" },
    //...
];
我怎么把它转换成这样的东西

var output = [
    {
        Name: "Europe",
        Children: [
            {
                Name: "Germany",
                Children: [
                    {
                        Name: "Frankfurt",
                        Id: 1,
                        Attribute1: "some attribute"
                    },
                    {
                        Name: "Munich",
                        Id: 2,
                        Attribute1: "some attribute"
                    }
                ]
            },
            {
                Name: "France",
                Children: [
                    {
                        Name: "Paris",
                        Id: 12,
                        Attribute1: "some attribute"
                    },
                    {
                        Name: "Marseille",
                        Id: 14,
                        Attribute1: "some attribute"
                    }
                ]
            }
        ],
        //...
    },
    //...
];
我做了一些搜索,发现了一些非常相似的主题: 但我想要的是嵌套数组和对象的组合,而不是上述解决方案中的对象树

请帮帮我,谢谢


<script>
    var input = [
        { Id: 1, LongName: "Europe;Germany;Frankfurt", Attribute1: "some attribute" },
        { Id: 2, LongName: "Europe;Germany;Munich", Attribute1: "some attribute" },
        { Id: 7, LongName: "Asia;Japan;Okinawa", Attribute1: "some attribute" },
        { Id: 8, LongName: "North America;US;Seattle", Attribute1: "some attribute" },
        { Id: 10, LongName: "Asia;China;Beijing", Attribute1: "some attribute" },
        { Id: 12, LongName: "Europe;France;Paris", Attribute1: "some attribute" },
        { Id: 14, LongName: "Europe;France;Marseille", Attribute1: "some attribute" },
        { Id: 5, LongName: "Asia;Japan;Tokyo", Attribute1: "some attribute" },
        { Id: 6, LongName: "Asia;Korea;Seoul", Attribute1: "some attribute" },
        { Id: 9, LongName: "Asia;Korea;Busan", Attribute1: "some attribute" },
        { Id: 11, LongName: "North America;US;New York", Attribute1: "some attribute" }
    ];
    let output = [];
    input.forEach((item) => {
        let names = item.LongName.split(';');
        let records = output.filter((rec) => {
            return rec.Name == names[0];
        });
        let rec = { Name: names[0], Children: [] };
        if (records.length > 0) rec = records[0];
        else output.push(rec);
        let childs = rec.Children.filter((rec) => {
            return rec.Name == names[1];
        });
        let child = { Name: names[1], Children: [] };
        if (childs.length > 0) child = childs[0];
        else rec.Children.push(child);
        child.Children.push({ Name: names[2], Id: item.Id, Attribute1: item.Attribute1 });
    });
    console.log(output);
</script>
变量输入=[ {Id:1,LongName:“欧洲;德国;法兰克福”,属性1:“某些属性”}, {Id:2,LongName:“欧洲;德国;慕尼黑”,属性1:“某些属性”}, {Id:7,LongName:“亚洲;日本;冲绳”,属性1:“某些属性”}, {Id:8,LongName:“北美;美国;西雅图”,属性1:“某些属性”}, {Id:10,LongName:“亚洲;中国;北京”,属性1:“某些属性”}, {Id:12,LongName:“欧洲;法国;巴黎”,属性1:“某些属性”}, {Id:14,LongName:“欧洲;法国;马赛”,属性1:“某些属性”}, {Id:5,LongName:“亚洲;日本;东京”,属性1:“某些属性”}, {Id:6,LongName:“亚洲;韩国;首尔”,属性1:“某些属性”}, {Id:9,LongName:“亚洲;韩国;釜山”,属性1:“某些属性”}, {Id:11,LongName:“北美;美国;纽约”,属性1:“某些属性”} ]; 让输出=[]; input.forEach((项目)=>{ 让name=item.LongName.split(“;”); 让记录=输出。过滤器((rec)=>{ 返回rec.Name==名称[0]; }); 让rec={Name:names[0],子项:[]}; 如果(records.length>0)rec=records[0]; else输出推送(rec); 让childs=rec.childs.filter((rec)=>{ 返回rec.Name==names[1]; }); let child={Name:names[1],Children:[]}; 如果(childs.length>0)child=childs[0]; else rec.Children.push(child); push({Name:names[2],Id:item.Id,Attribute1:item.Attribute1}); }); 控制台日志(输出);

使用
forEach
循环遍历
在每个项目上,将名称拆分为

选中要推送的适当数组(父数组或子数组)。(使用
ptr\u arr

const进程=(输入,输出=[])=>{
input.forEach(({LongName,…rest})=>{
const keys=LongName.split(“;”);
设ptr_arr=输出;
while(keys.length>0){
让key=keys.shift();
如果(keys.length==0){
//它的叶子
ptr_arr.push({Name:key,…rest});
}否则{
让index=ptr_arr.findIndex(({Name})=>Name==key);
如果(索引==-1){
ptr_arr.push({Name:key,Children:[]});
索引=ptr_arr.length-1;
}
ptr_arr=ptr_arr[index];
}
}
});
返回输出;
};
变量输入=[
{Id:1,LongName:“欧洲;德国;法兰克福”,属性1:“某些属性”},
{Id:2,LongName:“欧洲;德国;慕尼黑”,属性1:“某些属性”},
{Id:7,LongName:“亚洲;日本;冲绳”,属性1:“某些属性”},
{Id:8,LongName:“北美;美国;西雅图”,属性1:“某些属性”},
{Id:10,LongName:“亚洲;中国;北京”,属性1:“某些属性”},
{Id:12,LongName:“欧洲;法国;巴黎”,属性1:“某些属性”},
{Id:14,LongName:“欧洲;法国;马赛”,属性1:“某些属性”},
{Id:5,LongName:“亚洲;日本;东京”,属性1:“某些属性”},
{Id:6,LongName:“亚洲;韩国;首尔”,属性1:“某些属性”},
{Id:9,LongName:“亚洲;韩国;釜山”,属性1:“某些属性”},
{
Id:11,
LongName:“北美;美国;纽约”,
属性1:“某些属性”,
},
];
console.log(进程(输入))
var输入=[
{Id:1,LongName:“欧洲;德国;法兰克福”,属性1:“某些属性”},
{Id:2,LongName:“欧洲;德国;慕尼黑”,属性1:“某些属性”},
{Id:7,LongName:“亚洲;日本;冲绳”,属性1:“某些属性”},
{Id:8,LongName:“北美;美国;西雅图”,属性1:“某些属性”},
{Id:10,LongName:“亚洲;中国;北京”,属性1:“某些属性”},
{Id:12,LongName:“欧洲;法国;巴黎”,属性1:“某些属性”},
{Id:14,LongName:“欧洲;法国;马赛”,属性1:“某些属性”},
{Id:5,LongName:“亚洲;日本;东京”,属性1:“某些属性”},
{Id:6,LongName:“亚洲;韩国;首尔”,属性1:“某些属性”},
{Id:9,LongName:“亚洲;韩国;釜山”,属性1:“某些属性”},
{Id:11,LongName:“北美;美国;纽约”,属性1:“某些属性”},
];
输出=输入。减少((结果,项目)=>
{ 
设g=item.LongName.split(“;”),node1,node2,node3;
node1=result.find(({Name})=>Name==g[0]);if(node1)
node2=node1.Children.find(({Name})=>Name==g[1]);if(node2)
node3=node2.Children.find({Name}=>Name==g[2]);
if(node1==未定义)result.push({Name:g[0],子项:[{Name:g[1],子项:[{Name:g[2],Id:item.Id,Attribute1:item.Attribute1}]})
其他的
if(node2==未定义)node1.Children.push({Name:g[1],子项:[{Name:g[2],Id:item.Id,Attribute1:item.Attribute1}]})
其他的
if(node3==未定义)node2.Children.push({Name:g[2],Id:item.Id,Attribute1:item.Attribute1})
其他的
log(item.LongName+“路径已存在”);
返回结果;
}, []
);

控制台日志(输出)这里是一个使用嵌套调用的解决方案

const output=input.reduce((a,{LongName,…attributes})=>{
常量级别=LongName.split(“;”);
const lastLevel=levels.pop();
innerChildArray=levels.reduce((b,levelName)=>{
levelIndex=b.findIndex(({Name})=>Name==levelName);
如果(levelIndex==-1){
levelIndex=b.push({Name:levelName,子项:[]})-1;
}
返回b[levelIndex]。子级;
},a);
小酒馆