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;
原文:https://www.cnblogs.com/caoke/p/14793586.html