Array.prototype.pushOnly=function(one){ if(this.indexOf(one)===-1){ this.push(one) } } /* * 分类器*/ class ArraySplit { constructor(getDis,sArr,maxDeep) { this.getDis=getDis; this.sArr=sArr; this.maxDeep=maxDeep||8; this.tagMap={}; this.dataMap={}; const indexArr=sArr.map(function (item,i) { return i; }) this.splitByIndex(indexArr,'') console.log(this.tagMap) console.log(this.dataMap) } //计算元素key的最大长度dis、最大长度对应的元素arr getMaxKey(key1,indexArr) { const sArr=this.sArr const getDis=this.getDis let maxDis=0; let allDis=0; let arr=[] indexArr.forEach(function (key2) { const dis=getDis(sArr[key1],sArr[key2]) allDis=allDis+dis; if(dis>maxDis){ arr=[key2] maxDis=dis }else if(dis===maxDis){ arr.push(key2) } }) return { key:key1, dis:maxDis, allDis:allDis, arr } } //获取数据分割线(两个风格点) getSplitLine(indexArr) { const sArr=this.sArr //找到对边的点 let line=this.getMaxKey(indexArr[0],indexArr,sArr) let isMax=false; let moreKey; let maxDis=0; while (!isMax){ taskArr.push(line.key) isMax=true; maxDis=0; for(let i=0;i<line.arr.length;i++){ const key=line.arr[i] if(key!==line.key){ const m2=this.getMaxKey(key,indexArr,sArr) const dis=m2.allDis; if(m2.dis>line.dis||m2.dis===line.dis&&m2.arr.length>line.arr.length||m2.dis===line.dis&&m2.arr.length===line.arr.length&&m2.allDis>line.allDis){ line=m2 isMax=false; break }else if(dis>maxDis){ maxDis=dis moreKey=key } } } } let lessKey=line.key; return [lessKey,moreKey,parseInt(line.dis)] } getTags(ele,line){ const sArr=this.sArr const getDis=this.getDis const tags=[] const left=getDis(sArr[line[0]],ele); const right=getDis(sArr[line[1]],ele); if(left*2<line[2]){ tags.push(0) if(left*8>3*line[2]){ tags.push(2) } }else if(right*2<line[2]){ tags.push(1) if(right*8>3*line[2]){ tags.push(2) } }else{ tags.push(2) } return tags; } splitByIndex(indexArr,deep){ if(deep.length>=this.maxDeep){ this.dataMap[deep]=indexArr return } const sArr=this.sArr const line=this.getSplitLine(indexArr) const data=[[],[],[]] indexArr.forEach( (key) =>{ const tags=this.getTags(sArr[key],line); tags.forEach(function (tag) { data[tag].push(key) }) }) data.forEach( (arr0,i)=> { const tag0=deep+String(i) if(arr0.length>2){ this.splitByIndex(arr0,tag0) }else if(arr0.length){ this.dataMap[tag0]=arr0; } }) if(data[2].length===0){ this.dataMap[deep]=indexArr }else{ this.tagMap[deep]=line; } } getNearTags(ele){ let t0Arr=[''] let t1Arr=[] let lock=false; while (!lock){ const cArr=[] t0Arr.forEach((path)=> { const line=this.tagMap[path] if(line){ const tags=this.getTags(ele,line) tags.forEach(function (tag) { cArr.pushOnly(path+tag) }) }else{ t1Arr.pushOnly(path) } }) if(cArr.length>0){ t0Arr=cArr; }else{ lock=true; t0Arr.forEach(function (path) { t1Arr.pushOnly(path) }) } } return t1Arr.reverse(); } //对数组分类,成2部分 getNearEles(ele){ const tags=this.getNearTags(ele) console.log(tags) const eles=[] tags.forEach((tag)=> { this.dataMap[tag].forEach((i)=>{ eles.pushOnly(i) }) }) return eles } } module.exports=ArraySplit;