分类器

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