前端处理树形数组的几种情况

概览

像日常开发中,经常会有对树形结构的数组的处理,比如数组的扁平化、根据值去查找对应的值等。下面就以省、市、区树形数组为基础数据来举例。话不多说,开整。

一. 树形数组

代码示例

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;  
};

三. 根据对象属性查找对应的子集

  1. 获取带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')

缺点: 据最后一级的属性值去获取时得到的值总是空数组

  1. 可以根据每个层级的属性值,去获取对应的子集,最后一级对应的值为对象,需要兼容处理。

代码示例如下:

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')
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值