我有“实体”和“实体模板”。顶级实体被绑定到一个实体模板,该模板是"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文档:
https://docs.mongodb.com/manual/tutorial/model-tree-structures-with-materialized-paths/
我有一个稍有不同的用例,“实体模板”是顶层父级,但在“实体”中,用例是相同的。任何洞察力都是非常值得欣赏的。
发布于 2020-02-21 12:08:36
最后,我成功地编写了代码,并进行了大量的调试,因为有很多陷阱。
这个想法是在几次遍历中生成json,每次计算剩余元素的数量。
如果该数字在一次传递到另一次传递时没有减少,则pgm将发送错误并停止。
对于要添加的每个元素,我们计算假设的父getParentKey()
,它返回一个包含所有父元素列表的表
然后,您必须使用此列表在表中找到直接父元素,从根开始,如果父元素不存在,则该元素将保留在表中,并将在下一次重试。
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 Result = []
;
let unDone = []
, source = entities
;
let cpt = 0 // just for stoping infinite loop on error
;
do
{
unDone = setResult( source, unDone.length )
source = unDone;
if (++cpt > 10) throw 'mince! something is rotten in the state of Denmark...'
}
while
(unDone.length>0)
;
/* --------------------------------------------------------*/
console.log( 'result===', JSON.stringify(Result,0,2 ) )
/* --------------------------------------------------------*/
function setResult( arrayIn, nb_rej )
{
let orphans = [];
for (let elData of arrayIn)
{
let newEl = { ...elData, children: null }
, parAr = getParentKey(elData.path)
if (parAr.length===0)
{ Result.push(newEl) }
else
{
let resParent = Result;
do
{
let rech = parAr.pop()
, fPar = resParent.find(treeElm=>(treeElm.id===rech.id && treeElm.path===rech.path))
;
if (fPar)
{
if (fPar.children===null)
fPar.children = []
;
resParent = fPar.children
}
else // throw `parent element not found : id:'${rech.id}', path:'${rech.path}'` ;
{
orphans.push( { ...elData } )
resParent = null
parAr.length = 0
}
}
while
(parAr.length>0)
;
if (resParent) resParent.push(newEl);
}
}
if ( orphans.length>0 && orphans.length == nb_rej )
throw ` ${nb_rej} children element(s) without parent !'`;
return orphans
}
function getParentKey( path )
{ // return array of parent element
let rep = []
, par = path
, lev, bKey, xCom, idK;
do
{
bKey = par.substring(0, par.lastIndexOf(',')) // remove last ','
lev = bKey.match(/,/g).length -1
if (lev>0)
{
xCom = bKey.lastIndexOf(',')
par = bKey.substring(0, xCom) +','
idK = bKey.substring(++xCom)
rep.push({ path:par, id:idK })
} }
while
(lev>0)
return rep
}
.as-console-wrapper { max-height: 100% !important; top: 0; }
发布于 2020-02-21 06:54:26
我已经做到了..。我已经添加了一种类型,以防止任何键混乱。
const data =
[ { id: '1', name: '1', path: ',templateId1,' }
, { id: '2', name: '2', path: ',templateId1,' }
, { id: '2-1', name: '2-1', path: ',templateId1,2,' }
, { id: '1-1', name: '1-1', path: ',templateId1,1,' }
, { id: '1-1-1', name: '1-1-1', path: ',templateId1,1,1-1,'}
]
let result = []
, parents = [ {children: result} ]
;
for (let elData of data.sort((a,b)=>a.id.localeCompare(b.id)))
{
let newEl = { ...elData, children: null }
, level = (elData.id.match(/-/g)||'').length // count number of '-'
;
if (parents[level].children===null)
{ parents[level].children = [] }
parents[level].children.push( newEl )
parents[++level] = newEl
}
console.log(JSON.stringify(result,0,2 ) ) // for testing
.as-console-wrapper { max-height: 100% !important; top: 0; }
https://stackoverflow.com/questions/60326759
复制相似问题