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进行扩展