轮训获取树形结构的每一条线

/**
 * 获取树形结构的每一条线
 * @param tree
 */
export function recurTree(tree) {
  let res = [];
  let nodeArr = [];
  const findPath = (res, tree, nodePath) => {
    if (tree.children) {
      tree.children.forEach((item, index) => {
        findPath(res, tree.children[index], [...nodePath, item.unitId])
      })
    } else {
      res.push(nodePath);
    }
  }
  findPath(res, tree, nodeArr);
}

// 最后数据结构示例
[
    [
        "3_1",
        "3_5",
        "4_1"
    ],
    [
        "3_1",
        "3_5",
        "4_12",
        "4_13"
    ],
    [
        "3_1",
        "3_5",
        "4_12",
        "4_14"
    ],
    [
        "3_1",
        "3_5",
        "4_2"
    ],
    [
        "1_111",
        "2_1082"
    ],
    [
        "1_111",
        "3_11",
        "4_15"
    ]
]

获取一个树形结构的某一个树形的一维数组,flat(num)代表需要获取的层数,Infinity则为获取全部

// 如此处的data可为el-cascader点击后获取到的数据
data.flat(Infinity).filter(item => item != null)

// 如[[1,2], [2,3], [5,6,7], [[1,2,3], [6,7,8]]] 会变为 [1, 2, 2, 3, 5, 6, 7, 1, 2, 3, 6, 7, 8]

根据某一个节点获取所有的祖级节点

export function treeFindPath (tree, func, path = []) {
  if (!tree) return []
  for (const data of tree) {
    path.push(data.id)
    if (func(data)) return path
    if (data.children) {
      const findChildren = treeFindPath(data.children, func, path)
      if (findChildren.length) return findChildren
    }
    path.pop()
  }
  return []
}

// 使用示例,比如用于得到el-cascader某一级的entId,回显于组件中
treeFindPath(this.options, data => data.id === this.dataForm.entId);

数组去重new Set()

this.entIdList = [...new Set([...this.defaultChoose.flat(Infinity), ...opt.unitIdList])];

时间格式化

export function parseTime(time, pattern) {
  if (arguments.length === 0 || !time) {
    return null
  }
  const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
  let date
  if (typeof time === 'object') {
    date = time
  } else {
    if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
      time = parseInt(time)
    } else if (typeof time === 'string') {
      time = time.replace(new RegExp(/-/gm), '/')
    }
    if ((typeof time === 'number') && (time.toString().length === 10)) {
      time = time * 1000
    }
    date = new Date(time)
  }
  const formatObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay()
  }
  const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
    let value = formatObj[key]
    // Note: getDay() returns 0 on Sunday
    if (key === 'a') {
      return ['日', '一', '二', '三', '四', '五', '六'][value]
    }
    if (result.length > 0 && value < 10) {
      value = '0' + value
    }
    return value || 0
  })
  return time_str
}


// 使用示例
parseTime(date1, '{y}-{m}-{d}')
parseTime(date1, '{h}:{i}')

对象深拷贝

export const deepClone = data => {
  var type = getObjType(data)
  var obj
  if (type === 'array') {
    obj = []
  } else if (type === 'object') {
    obj = {}
  } else {
    // 不再具有下一层次
    return data
  }
  if (type === 'array') {
    for (var i = 0, len = data.length; i < len; i++) {
      obj.push(deepClone(data[i]))
    }
  } else if (type === 'object') {
    for (var key in data) {
      obj[key] = deepClone(data[key])
    }
  }
  return obj
}

构造树形结构

/**
 * 构造树型结构数据
 * @param {*} data 数据源
 * @param {*} id id字段 默认 'id'
 * @param {*} parentId 父节点字段 默认 'parentId'
 * @param {*} children 孩子节点字段 默认 'children'
 * @param {*} rootId 根Id 默认 0
 */
export function handleTree(data, id, parentId, children, rootId) {
  id = id || 'id'
  parentId = parentId || 'parentId'
  children = children || 'children'
  rootId = rootId || 0
  //对源数据深度克隆
  const cloneData = JSON.parse(JSON.stringify(data))
  //循环所有项
  const treeData = cloneData.filter(father => {
    let branchArr = cloneData.filter(child => {
      //返回每一项的子级数组
      return father[id] === child[parentId]
    })
    branchArr.length > 0 ? father.children = branchArr : ''
    //返回第一层
    return father[parentId] === rootId
  })
  return treeData != '' ? treeData : data
}

树形结构中将为空的children设置为undefined,可以用于去除el-cascader最后一级空的列表

export const processSubjectTree = tree => {
  tree.forEach(branch => {
    if (branch.children) {
      if (branch.children.length) {
        processSubjectTree(branch.children);
      } else {
        branch.children = undefined;
      }
    }
  });
  return tree;
};

计算多个坐标点的中心点

export const getCenterPoint = (geoCoordinateList) => {
  const geoCoordinateListFlat = geoCoordinateList.reduce((s, v) => {
    return (s = s.concat({lng: v[0], lat: v[1]}))
  }, [])
  const total = geoCoordinateListFlat.length
  let X = 0
  let Y = 0
  let Z = 0
  for (const g of geoCoordinateListFlat) {
    const lat = g.lat * Math.PI / 180
    const lon = g.lng * Math.PI / 180
    const x = Math.cos(lat) * Math.cos(lon)
    const y = Math.cos(lat) * Math.sin(lon)
    const z = Math.sin(lat)
    X += x
    Y += y
    Z += z
  }

  X = X / total
  Y = Y / total
  Z = Z / total
  const Lon = Math.atan2(Y, X)
  const Hyp = Math.sqrt(X * X + Y * Y)
  const Lat = Math.atan2(Z, Hyp)

  return [Lon * 180 / Math.PI, Lat * 180 / Math.PI]
}

// 如使用下列数据获取秦淮区的中心点
[
    [
        118.83298953125,
        31.98819846875
    ],
    [
        118.797345,
        31.973843
    ],
    [
        118.792867460938,
        31.9960305000001
    ],
    [
        118.757345,
        32.013843
    ],
    [
        118.757345,
        32.023843
    ],
    [
        118.767345,
        32.023843
    ],
    [
        118.83205203125,
        32.0128517890625
    ],
    [
        118.837345,
        31.993843
    ],
    [
        118.83298953125,
        31.98819846875
    ]
]

数组交集、并集、差集

 let a = new Set([1, 2, 3])
 let b = new Set([2, 3, 4])
 
//并集
console.log(new Set([...a, ...b]))
// 结果  {1, 2, 3, 4} 

 //交集
 console.log(new Set([...a].filter(v => b.has(v)))) // Set(2) {2, 3}
 
 //差集
 new Set([...a].filter(v => !b.has(v))) //  Set(1) {1}

Base64加密

export default function Base64() {
  // 私钥
  let _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
  // 加密
  this.encode = function (input) {
    var output = "";
    var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
    var i = 0;
    input = _utf8_encode(input);
    while (i < input.length) {
      chr1 = input.charCodeAt(i++);
      chr2 = input.charCodeAt(i++);
      chr3 = input.charCodeAt(i++);
      enc1 = chr1 >> 2;
      enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
      enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
      enc4 = chr3 & 63;
      if (isNaN(chr2)) {
        enc3 = enc4 = 64;
      } else if (isNaN(chr3)) {
        enc4 = 64;
      }
      output = output +
        _keyStr.charAt(enc1) + _keyStr.charAt(enc2) +
        _keyStr.charAt(enc3) + _keyStr.charAt(enc4);
    }
    return output;
  }
  // 解密
  this.decode = (input) => {
    var output = "";
    var chr1, chr2, chr3;
    var enc1, enc2, enc3, enc4;
    var i = 0;
    if (input === undefined || input == null) {

    } else {
      input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
      while (i < input.length) {
        enc1 = _keyStr.indexOf(input.charAt(i++));
        enc2 = _keyStr.indexOf(input.charAt(i++));
        enc3 = _keyStr.indexOf(input.charAt(i++));
        enc4 = _keyStr.indexOf(input.charAt(i++));
        chr1 = (enc1 << 2) | (enc2 >> 4);
        chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
        chr3 = ((enc3 & 3) << 6) | enc4;
        output = output + String.fromCharCode(chr1);
        if (enc3 !== 64) {
          output = output + String.fromCharCode(chr2);
        }
        if (enc4 !== 64) {
          output = output + String.fromCharCode(chr3);
        }
      }
      output = _utf8_decode(output);
      return output;
    }

  }
  // private method for UTF-8 encoding
  let _utf8_encode = (string) => {
    string = string.replace(/\r\n/g, "\n");
    var utftext = "";
    for (var n = 0; n < string.length; n++) {
      var c = string.charCodeAt(n);
      if (c < 128) {
        utftext += String.fromCharCode(c);
      } else if ((c > 127) && (c < 2048)) {
        utftext += String.fromCharCode((c >> 6) | 192);
        utftext += String.fromCharCode((c & 63) | 128);
      } else {
        utftext += String.fromCharCode((c >> 12) | 224);
        utftext += String.fromCharCode(((c >> 6) & 63) | 128);
        utftext += String.fromCharCode((c & 63) | 128);
      }
    }
    return utftext;
  }
  // private method for UTF-8 decoding
  let _utf8_decode = (utftext) => {
    var string = "";
    var i = 0;
    var c = c1 = c2 = 0;
    var c1 = 0;
    var c2 = 0;
    var c3 = 0;
    while (i < utftext.length) {
      c = utftext.charCodeAt(i);
      if (c < 128) {
        string += String.fromCharCode(c);
        i++;
      } else if ((c > 191) && (c < 224)) {
        c2 = utftext.charCodeAt(i + 1);
        string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
        i += 2;
      } else {
        c2 = utftext.charCodeAt(i + 1);
        c3 = utftext.charCodeAt(i + 2);
        string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
        i += 3;
      }
    }
    return string;
  }
}

// 使用
//new Base64().encode(url)