概览
像日常开发中,经常会有对树形结构的数组的处理,比如数组的扁平化、根据值去查找对应的值等。下面就以省、市、区树形数组为基础数据来举例。话不多说,开整。
一. 树形数组
代码示例
const baseData = [
{
code: '11',
name: '北京市',
children: [
{
code: '1101',
name: '市辖区',
children: [
{
code: '110101',
name: '东城区',
},
{
code: '110102',
name: '西城区',
}
]
}
]
},
{
code: '50',
name: '重庆市',
children: [
{
code: '5001',
name: '市辖区',
children: [
{
code: '500101',
name: '万州区',
},
{
code: '500102',
name: '涪陵区',
}
]
},
{
code: '5002',
name: '县',
children: [
{
code: '500229',
name: '城口县',
},
{
code: '500230',
name: '丰都县',
}
]
}
]
},
{
code: '36',
name: '江西省',
children: [
{
code: '3601',
name: '南昌市',
children: [
{
code: '360102',
name: '东湖区',
},
{
code: '360103',
name: '西湖区',
}
]
},
{
code: '3605',
name: '新余市',
children: [
{
code: '360502',
name: '渝水区',
},
{
code: '360521',
name: '分宜县',
},
],
}
]
}
]
二. 转换成市/区县结构,三层转变成两层
代码示例如下
export const getSimpData = () => {
const municipality = ['北京市', '上海市', '天津市', '重庆市'];
const result = [];
const cloneData = cloneDeep(baseData);
cloneData.forEach(province => {
// 判断是否是直辖市
if (municipality.includes(province.name)) {
// 如果是直辖市,特殊处理
const {code,name} = province;
const tempCity = { code,name,children: []};
const innerChildren = province.children.map(subitem => subitem.children).flat();
tempCity.children.push(...innerChildren);
result.push(tempCity)
} else {
// 对于自治区和省份,将子元素直接推入结果数组
result.push(...province.children);
}
});
return result;
};
三. 根据对象属性查找对应的子集
- 获取带chidren的子集
const getChildByCode = (data , val,type="code") => {
// 辅助函数,递归地在子项中查找
const findChildByCode = (items, val) => {
for (let i = 0; i < items.length; i++) {
if (items[i][type] === val) {
return items[i].children // 找到匹配的 code,返回其 children
}
if (items[i].children) {
const result = findChildByCode(items[i].children, val); // 递归在子项中查找
if (result.length > 0) {
return result; // 如果在子项中找到了,返回结果
}
}
}
return []; // 没有找到匹配的 code,返回空数组
};
}
使用示例:
getChildByCode(baseData, '3601')
缺点: 据最后一级的属性值去获取时得到的值总是空数组
- 可以根据每个层级的属性值,去获取对应的子集,最后一级对应的值为对象,需要兼容处理。
代码示例如下:
const getChildByCode = (data , val,type="code") => {
// 辅助函数,递归地在子项中查找
const findChildByCode = (items, val) => {
for (let i = 0; i < items.length; i++) {
if (items[i][type] === val) {
return items[i].children ? items[i].children: items[i]
}
if (items[i].children) {
const result = findChildByCode(items[i].children, val); // 递归在子项中查找
if ((Array.isArray(result) && result.length > 0) || (typeof result === 'object' && Object.keys(result).length > 0)) {
return result; // 如果在子项中找到了,返回结果
}
}
}
return []; // 没有找到匹配的 code,返回空数组
};
// 从根级别开始查找
return findChildByCode(data, val);
};
使用示例:
getChildByCode(baseData, '360502')