因项目需要,现有不确定数目的节点,但是有固定的类型和名字,如
[
{type:nodeA1,name:节点A}
{type:nodeA2,name:节点A}
{type:nodeB,name:节点B}
{type:nodeC,name:节点C}
]
创建节点的时候需要对名字相同的节点自增命名,暂定为text属性,如绘制节点的时候,绘制nodec,其节点text为节点C1,继续绘制nodec,其text为节点C2,以此类推,继续,绘制nodeA1,则其text为节点A1,继续绘制nodeA1,则其text为节点A2,继续绘制nodeA2,则其text为节点A3,继续绘制nodeA1,则其text为节点A4,此外,修改和删除节点后,新节点要补全命名空缺。
1.原始方法
原始方法是每次绘制都对现有节点的数组进行遍历,总共有几个就几加1作为当前的序号,但是如果删除之后就会留空缺,并且对于名字一样类型不同的节点只能用(新)来进行区分
2.解决方案
设置计数器,先将所有节点都设置一个计数器,计数器的技术格式可以自己修改,我是为了方便判断,所以直接把键当成了判断的标准,方便用in进行判断,
(0)正则表达式
function predix(str){
newstr = str.match(/^(.*?)(\d+)$/)
if(newstr)
return [newstr[1],newstr[2]];
else
return [str,'0'];
}
(1)创建自动扩展的计数器,并将name属性隐含进去,方便之后别的判断
devtypelist = response
//设置计数器
for (let i = 0; i < response.length; i++) {
t = predix(response[i].dev_type)
variable_name =t[0]//得到type的前缀
if(!(variable_name in counters))
counters[variable_name]= {'0':true,[response[i].name]:true}
}
(2)创建节点
const t = predix(nodeType)
let pretype = t[0]
for (let i = 0; i < 999; i++) {
if(counters[pretype][i.toString()])
continue;
else{
text = text+i.toString();
counters[pretype][i.toString()]=true;
break;
}
}
(3)删除节点之后
const t = predix(nodetype)
let pretype = t[0]//找到计数器的名字
const p = text.match(/(\d+)|(\D+)/g)
let name = p[0]//得到节点名中的前缀部分
let i = p[1]//得到自己的自增顺序
if(name in counters[pretype])//先判断一下是不是人为修改过的名字
counters[pretype][i.toString()] = false
(4)修改节点名称
为了增加容错,修改节点之前和之后都要判断,以防计数器漏设
const c = predix(nodetype)
let pretype = c[0]//找到计数器的名字
const before = text.match(/(\d+)|(\D+)/g)
let name = before[0]//得到原节点名中的前缀部分
let num = before[1]//得到自己的自增顺序
if(name in counters[pretype])//先判断一下是不是人为修改过的名字
counters[pretype][num.toString()] = false
const later = newtext.match(/(\d+)|(\D+)/g)
name = later[0]//得到修改后节点名中的前缀部分
num = later[1]//得到自己的自增顺序
if(name in counters[pretype])//先判断一下是不是与系统名一样
counters[pretype][num.toString()] = true
其中一些细节可以根据自己的实际情况修改,这个算法不算完美但是解决了问题(hhhh)