js树结构筛选,关键字查询和根据id值或某个属性的值从树结构中查询数据

js树结构筛选,关键字查询和根据id值或某个属性的值从树结构中查询数据,可以便捷的从属性数据中查找出所需数据

前言

  • tree树结构数据通过关键字查询 相等于是 模糊查询数据
  • 根据id值或某个属性的值从树结构中查询数据 相当于是 精准查询数据

tree树结构数据通过关键字查询

/**
 * 通过关键字,筛选tree数据
 * @param {String} value 筛选字符串
 * @param {Array} arr 要筛选数据
 * @param {String} childrenKey 树子节点
 * @returns 筛选后的数据
 */
export const TreeDataList = (value = '', arr, childrenKey = 'subList', filterName = 'name') => {
  if (!arr) {
    return []
  }
  let newList = []
  arr.forEach((item) => {
    if (item[filterName].indexOf(value) > -1) {
      const Children = TreeDataList(value, item[childrenKey])
      const obj = {
        ...item
      }
      obj[childrenKey] = Children
      newList.push(obj)
    } else {
      if (item[childrenKey] && item[childrenKey].length > 0) {
        const Children = TreeDataList(value, item[childrenKey])
        const obj = {
          ...item
        }
        obj[childrenKey] = Children
        if (Children && Children.length > 0) {
          newList.push(obj)
        }
      }
    }
  })
  return newList
}

tree树结构数据根据id值或某个属性的值从树结构中查询数据

普通方式,属性值为普通字符类型(String、Number、boolean等)

/**
 * 根据id值或某个属性的值从树结构中查询数据
 * @param {Array} treeArray 树结构数据
 * @param {String|Number|Boolean|null} id 对比的id的值
 * @param {String} childrenKey 子集的key名, 默认 children
 * @returns 返回存在的数据,不存在返回null
 */
export function treeFindById(treeArray, id, childrenKey = 'children') {
  for (let node of treeArray) {
    // id值对比
    if (node.id === id) {
      return node
    }

    if (node[childrenKey] && node[childrenKey].length > 0) {
      const foundElement = treeFindById(node[childrenKey], id)
      if (foundElement) {
        return foundElement
      }
    }
  }

  return null
}

进阶方式,可以使用任意值,包括Array和Object等

进阶方法需要用到对比函数对比任意两个值是否相等

对比任意两个值是否相等

/**
 * 判断是否为基础类型object(这为基础类型判断,所以数组和对象是区分不开的,只为下边对比使用)
 * @param {any} obj 传入要判断的数据类型
 * @returns 为object的为 true, 否则为false
 */
export const isObject = (obj) => {
  return obj !== null && typeof obj === 'object'
}

/**
 * 判断两个值是否相等
 * @param {any} a 任意数据类型
 * @param {any} b 任意数据类型
 * @returns true 为一致, false 为不相等
 */
export const looseEqual = (a, b) => {
  if (a === b) {
    return true
  }
  let isObjectA = isObject(a)
  let isObjectB = isObject(b)
  if (isObjectA && isObjectB) {
    try {
      let isArrayA = Array.isArray(a)
      let isArrayB = Array.isArray(b)
      if (isArrayA && isArrayB) {
        return (
          a.length === b.length &&
          a.every(function (e, i) {
            return looseEqual(e, b[i])
          })
        )
      } else if (a instanceof Date && b instanceof Date) {
        return a.getTime() === b.getTime()
      } else if (!isArrayA && !isArrayB) {
        let keysA = Object.keys(a)
        let keysB = Object.keys(b)
        return (
          keysA.length === keysB.length &&
          keysA.every(function (key) {
            return looseEqual(a[key], b[key])
          })
        )
      } else {
        /* istanbul ignore next */
        return false
      }
    } catch (e) {
      /* istanbul ignore next */
      return false
    }
  } else if (!isObjectA && !isObjectB) {
    return String(a) === String(b)
  } else {
    return false
  }
}
进阶版,根据id值或某个属性的值从树结构中查询数据
/**
 * 根据id值或某个属性的值从树结构中查询数据,id为任意值
 * @param {Array} treeArray 树结构数据
 * @param {any} id 对比的id的值, 可以是任意字符,包括数组、对象
 * @param {String} childrenKey 子集的key名, 默认 children
 * @returns 返回存在的数据,不存在返回null
 */
export function treeFindById(treeArray, id, childrenKey = 'children') {
  for (let node of treeArray) {
    // 任意id值对比, 如果只是基础数据,也可以使用 node.id === id
    // 如需使用其他属性对比,将node.id 改为其他即可,也可在函数参数中增加idKey进行扩展
    if (looseEqual(node.id, id)) {
      return node
    }

    if (node[childrenKey] && node[childrenKey].length > 0) {
      const foundElement = treeFindById(node[childrenKey], id)
      if (foundElement) {
        return foundElement
      }
    }
  }

  return null
}

该方法默认为id对比,如需使用其他属性对比,将node.id 改为其他即可,也可在函数参数中增加idKey进行扩展

上一篇:[面试] java开发面经-1


下一篇:SpringBoot在高校竞赛平台开发中的优化策略