Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/387.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.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_Mongodb_Materialized Path Pattern - Fatal编程技术网

Javascript 从物化路径创建特定的树结构

Javascript 从物化路径创建特定的树结构,javascript,arrays,mongodb,materialized-path-pattern,Javascript,Arrays,Mongodb,Materialized Path Pattern,我有实体和实体模板。顶级实体绑定到一个实体模板,即templateId1。从那里,一个实体通过使用其id绑定到路径中的另一个实体。我试图以一种高效的方式结束以下数据结构: const entities = [ { id: 'xi32', name: 'Some name', path: ',templateId1,' }, { id: 'x382', name: 'Some name 2', path: ',templateId1,xi

我有实体和实体模板。顶级实体绑定到一个实体模板,即templateId1。从那里,一个实体通过使用其id绑定到路径中的另一个实体。我试图以一种高效的方式结束以下数据结构:

const entities = [
  {
    id: 'xi32',
    name: 'Some name',
    path: ',templateId1,'
  },
  {
    id: 'x382',
    name: 'Some name 2',
    path: ',templateId1,xi32,'
  },
  {
    id: '2oxwo',
    name: 'Some name 3',
    path: ',templateId1,xi32,x382,'
  },
  {
    id: '2',
    name: '2',
    path: ',templateId1,'
  },
  {
    id: '2-2',
    name: '2-2',
    path: ',templateId1,2,'
  },
  {
    id: '3-3',
    name: '3-3',
    path: ',templateId1,3,'
  },
  {
    id: '3-3-3',
    name: '3-3-3',
    path: ',templateId1,3,3-3,'
  },
  {
    id: '3-3-3-3',
    name: '3-3-3-3',
    path: ',templateId1,3,3-3,3-3-3,'
  },
  {
    id: '3',
    name: '3',
    path: ',templateId1,'
  }
];

const desiredResult = [
      {
        id: 'xi32',
        name: 'Some name',
        path: ',templateId1,',
        children: [
          {
            id: 'x382',
            name: 'Some name 2',
            path: ',templateId1,xi32,',
            children: [
              {
                id: '2oxwo',
                name: 'Some name 3',
                path: ',templateId1,xi32,x382,',
                children: null
              }
            ]
          }
        ]
      },
      {
        id: '2',
        name: '2',
        path: ',templateId1,',
        children: [
          {
            id: '2-2',
            name: '2-2',
            path: ',templateId1,2,',
            children: null
          }
        ]
      },
      {
        id: '3',
        name: '3',
        path: ',templateId1,',
        children: [
          {
            id: '3-3',
            name: '3-3',
            path: ',templateId1,3,',
            children: [
              {
                id: '3-3-3',
                name: '3-3-3',
                path: ',templateId1,3,3-3,',
                children: [
                  {
                    id: '3-3-3-3',
                    name: '3-3-3-3',
                    path: ',templateId1,3,3-3,3-3-3,',
                    children: null
                  }
                ]
              }
            ]
          }
        ]
      }
    ];
该结构的最初灵感来自MongoDB文档:

我有一个稍微不同的用例,实体模板是顶层父级,但在实体中,用例是相同的。非常感谢您的任何见解。

我已经做到了。。。 我添加了一种防止任何键紊乱的排序

常数数据= [{id:'1',name:'1',path:',templateId1',} ,{id:'2',名称:'2',路径:',templateId1',} ,{id:'2-1',名称:'2-1',路径:',templateId1,2',} ,{id:'1-1',名称:'1-1',路径:',templateId1,1',} ,{id:'1-1-1',名称:'1-1-1',路径:',templateId1,1,1-1',} ] 让结果=[] ,parents=[{children:result}] ; 对于data.sorta的let elData,b=>a.id.localeCompareb.id { 让newEl={…elData,children:null} ,level=elData.id.match/-/g | |长度//计数'-'的数量 ; 如果父级[级别]。子级===null {parents[level]。children=[]} 父级[级别].children.push newEl 父母[++level]=newEl } console.logJSON.stringifyresult,0,2//用于测试 .作为控制台包装{max height:100%!important;top:0;}我已完成此操作。。。 我添加了一种防止任何键紊乱的排序

常数数据= [{id:'1',name:'1',path:',templateId1',} ,{id:'2',名称:'2',路径:',templateId1',} ,{id:'2-1',名称:'2-1',路径:',templateId1,2',} ,{id:'1-1',名称:'1-1',路径:',templateId1,1',} ,{id:'1-1-1',名称:'1-1-1',路径:',templateId1,1,1-1',} ] 让结果=[] ,parents=[{children:result}] ; 对于data.sorta的let elData,b=>a.id.localeCompareb.id { 让newEl={…elData,children:null} ,level=elData.id.match/-/g | |长度//计数'-'的数量 ; 如果父级[级别]。子级===null {parents[level]。children=[]} 父级[级别].children.push newEl 父母[++level]=newEl } console.logJSON.stringifyresult,0,2//用于测试
.作为控制台包装{max height:100%!important;top:0;}最后,我通过大量调试成功地编写了此代码,因为有很多陷阱

其思想是将json分几次传递,每次计算剩余元素的数量

如果从一个过程到另一个过程,此数字没有减少,则pgm发送错误并停止

对于要添加的每个元素,我们计算假定的父getParentKey,它返回其所有父元素列表的表

然后必须使用此列表在表中找到直接父元素,从根开始,如果父元素不存在,则该元素将保留在表中,并将在下一步重试

常量实体= [{id:'xi32',name:'Some name',path:',templateId1',} ,{id:'x382',name:'Some name 2',path:',templateId1,xi32',} ,{id:'2oxwo',name:'Some name 3',path:',templateId1,xi32,x382',} ,{id:'2',名称:'2',路径:',templateId1',} ,{id:'2-2',名称:'2-2',路径:',templateId1,2',} ,{id:'3-3',名称:'3-3',路径:',templateId1,3',} ,{id:'3-3-3',名称:'3-3-3',路径:',templateId1,3,3-3',} ,{id:'3-3-3',名称:'3-3-3',路径:',templateId1,3,3-3,3-3',} ,{id:'3',name:'3',path:',templateId1',} ]; 常量结果=[] ; 撤消=[] ,source=实体 ; 设cpt=0//仅用于在出错时停止无限循环 ; 做 { unDone=setResult源,unDone.length 来源=未完成; 如果++cpt>10抛出“切碎!丹麦州有东西腐烂了…” } 虽然 撤消。长度>0 ; /* ----------------------------*/ console.log'result==',JSON.stringifyResult,0,2 /* ----------------------------*/ 函数setResult arrayIn,nb_rej { 让孤儿=[]; 为了阿拉因的艾尔达 { 让newEl={…elData,children:null} ,parAr=getParentKeyelData.path 如果平行长度===0 {Result.pushnewEl} 其他的 { 让resParent=结果; 做 { 让rech=parAr.pop ,fPar=resParent.findtreeElm=>treeElm.id==rech.id&&treeElm.path==rech.path ; 如果fPar { 如果fPar.children==null fPar.children=[] ; resParent=fPar.children } else//throw`parent element not found:id:'${rech.id}',path:'${rech.path}`; { orp 汉斯·普什{……埃尔达塔} resParent=null 平行长度=0 } } 虽然 平行长度>0 ; 如果resParent不是resParent.pushnewEl; } } 如果孤立.length>0&&olivers.length==nb_rej 抛出没有父元素的${nb_rej}子元素!'; 遣返孤儿 } 函数getParentKey路径 {//返回父元素的数组 让rep=[] PAR=路径 ,lev,bKey,xCom,idK; 做 { BKEY=PAR.SUBALIGIN 0,PAL.LASTENTROXOF','//移除最后一个'' lev=bKey.match/,/g.length-1 如果lev>0 { xCom=bKey.lastIndexOf',' PAR= BKEY子串0,XCOM+, idK=bKey.substring++xCom rep.push{path:par,id:idK} } } 虽然 列夫>0 退货代表 }
.作为控制台包装{max height:100%!important;top:0;}最后,我通过大量调试成功地编写了此代码,因为有很多陷阱

其思想是将json分几次传递,每次计算剩余元素的数量

如果从一个过程到另一个过程,此数字没有减少,则pgm发送错误并停止

对于要添加的每个元素,我们计算假定的父getParentKey,它返回其所有父元素列表的表

然后必须使用此列表在表中找到直接父元素,从根开始,如果父元素不存在,则该元素将保留在表中,并将在下一步重试

常量实体= [{id:'xi32',name:'Some name',path:',templateId1',} ,{id:'x382',name:'Some name 2',path:',templateId1,xi32',} ,{id:'2oxwo',name:'Some name 3',path:',templateId1,xi32,x382',} ,{id:'2',名称:'2',路径:',templateId1',} ,{id:'2-2',名称:'2-2',路径:',templateId1,2',} ,{id:'3-3',名称:'3-3',路径:',templateId1,3',} ,{id:'3-3-3',名称:'3-3-3',路径:',templateId1,3,3-3',} ,{id:'3-3-3',名称:'3-3-3',路径:',templateId1,3,3-3,3-3',} ,{id:'3',name:'3',path:',templateId1',} ]; 常量结果=[] ; 撤消=[] ,source=实体 ; 设cpt=0//仅用于在出错时停止无限循环 ; 做 { unDone=setResult源,unDone.length 来源=未完成; 如果++cpt>10抛出“切碎!丹麦州有东西腐烂了…” } 虽然 撤消。长度>0 ; /* ----------------------------*/ console.log'result==',JSON.stringifyResult,0,2 /* ----------------------------*/ 函数setResult arrayIn,nb_rej { 让孤儿=[]; 为了阿拉因的艾尔达 { 让newEl={…elData,children:null} ,parAr=getParentKeyelData.path 如果平行长度===0 {Result.pushnewEl} 其他的 { 让resParent=结果; 做 { 让rech=parAr.pop ,fPar=resParent.findtreeElm=>treeElm.id==rech.id&&treeElm.path==rech.path ; 如果fPar { 如果fPar.children==null fPar.children=[] ; resParent=fPar.children } else//throw`parent element not found:id:'${rech.id}',path:'${rech.path}`; { 孤儿。推{…elData} resParent=null 平行长度=0 } } 虽然 平行长度>0 ; 如果resParent不是resParent.pushnewEl; } } 如果孤立.length>0&&olivers.length==nb_rej 抛出没有父元素的${nb_rej}子元素!'; 遣返孤儿 } 函数getParentKey路径 {//返回父元素的数组 让rep=[] PAR=路径 ,lev,bKey,xCom,idK; 做 { BKEY=PAR.SUBALIGIN 0,PAL.LASTENTROXOF','//移除最后一个'' lev=bKey.match/,/g.length-1 如果lev>0 { xCom=bKey.lastIndexOf',' PAR= BKEY子串0,XCOM+, idK=bKey.substring++xCom rep.push{path:par,id:idK} } } 虽然 列夫>0 退货代表 }
.作为控制台包装器{max height:100%!important;top:0;}您希望在MongoDB或JavaScript中实现这一点吗?@mickl老实说,我不确定。如果可以的话,我喜欢在DB级别做一些事情,因为它通常性能更高,但特别是在这两种情况下都能做会更好。这样API就可以在需要时直接返回,树也可以用代码创建。@MisterJojo我尝试过使用它,但它采用了不同的结构,老实说,我很难解析其中的内容。我还在玩弄那个密码。@Jojo先生,我的错,那是个错误。我会编辑它。@MisterJojo我想可以,但我已经按路径排序了,所以最短路径排在第一位。假设它可以以任何顺序出现,那就太好了。我正在整理

在代码中只是为了安全。这是你想在MongoDB或JavaScript中实现的吗?@mickl老实说,我不确定。如果可以的话,我喜欢在DB级别做一些事情,因为它通常性能更高,但特别是在这两种情况下都能做会更好。这样API就可以在需要时直接返回,树也可以用代码创建。@MisterJojo我尝试过使用它,但它采用了不同的结构,老实说,我很难解析其中的内容。我还在玩弄那个密码。@Jojo先生,我的错,那是个错误。我会编辑它。@MisterJojo我想可以,但我已经按路径排序了,所以最短路径排在第一位。假设它可以以任何顺序出现,那就太好了。为了安全起见,我正在用代码对它重新排序。这看起来很棒。比我现在拥有的要短得多。需要稍微调整一下,因为关系/深度不是基于id或-,而是基于路径。我现在正在摆弄它。它应该是level=elData.path.match/,/g | |长度-2;2是为了摆脱,在弦的开始和结束。是的,男人工作得很好!通过了测试和我在评论中所做的更改。非常感谢:。我将完成我的解决方案,我也会发布它,但我喜欢你的。是的,这是我能看到的使它工作的唯一方法。身份证可以是任何东西。我只是用-作为例子。我的真实身份证是5e4dcc5e8b660466ca1fe916。因此,我们无法从id中找到任何可靠的深度/级别度量,这就是您试图达到的目的,对吗?这看起来很棒。比我现在拥有的要短得多。需要稍微调整一下,因为关系/深度不是基于id或-,而是基于路径。我现在正在摆弄它。它应该是level=elData.path.match/,/g | |长度-2;2是为了摆脱,在弦的开始和结束。是的,男人工作得很好!通过了测试和我在评论中所做的更改。非常感谢:。我将完成我的解决方案,我也会发布它,但我喜欢你的。是的,这是我能看到的使它工作的唯一方法。身份证可以是任何东西。我只是用-作为例子。我的真实身份证是5e4dcc5e8b660466ca1fe916。因此,我们无法从id中找到任何可靠的深度/级别度量,这就是您试图达到的目的,对吗?这太棒了!谢谢您:。我正在通读并试图理解代码,但它通过了所有测试。我也有一个解决方案,但我一直在和孩子们一起更新树。我可能也会把它写完,然后把它贴出来,但这很管用,所以可能不行。再次感谢!这太棒了!谢谢您:。我正在通读并试图理解代码,但它通过了所有测试。我也有一个解决方案,但我一直在和孩子们一起更新树。我可能也会把它写完,然后把它贴出来,但这很管用,所以可能不行。再次感谢!