前端实现递归查询省市区数据

为了更方便的记录怕后续用到,也是想让需要的人cv并不用那么焦虑,思路就是

  1. 在传入值中提取出要匹配的市和区名称。
  2. 遍历数据进行匹配,首先匹配市名称,然后在匹配到的市中再匹配区名称。
  3. 如果找到匹配的区,则按照当前逻辑保存对应的名称和代码。如果未找到匹配的区,则回退到匹配的市级并保存其名称和代码。
  4. 返回结果。
/**
 * 根据区名递归查询省市区相关联code和name
 * @param {*} data 原始数据
 * @param {*} name 区name
 * @returns 省市区code的数组
 */
export const getAreaByName = function (data, name) {
  let names = [];
  let codes = [];

  // 提取要匹配的市和区名称
  const matchResults = name.match(/([\u4e00-\u9fa5]+[市区])/g);
  if (!matchResults || matchResults.length < 2) {
    return null; // 匹配不到市和区名称,返回null或其他适当的值
  }
  const cityName = matchResults[0];
  const districtName = matchResults[1];

  function findCity(list, city, district, father) {
    const cityIndex = list.findIndex((ev) => ev.fullname === city);
    if (cityIndex > -1) {
      const cityItem = list[cityIndex];
      const districtIndex = cityItem.children ?
          cityItem.children.findIndex((ev) => ev.fullname === district) : -1;
      if (districtIndex > -1) {
        const districtItem = cityItem.children[districtIndex];
        names.unshift(districtItem.fullname);
        codes.unshift(districtItem.code);
        if (cityItem.fullname !== districtItem.fullname) {
          names.unshift(cityItem.fullname);
          codes.unshift(cityItem.code);
        }
        father && names.unshift(father.fullname) && codes.unshift(father.code);
        father && findCity([], father.fullname, cityItem.fullname);
        return;
      }
    }
    list.forEach((item) => {
      if (item.children && item.children.length > 0) { // 添加对非null和非空子项的检查
        findCity(item.children, city, district, item);
      }
    });
  }

  findCity(data, cityName, districtName);
  names = [...new Set(names)];
  codes = [...new Set(codes)];
  if (names.length < 3) names.unshift(names[0]);
  if (codes.length < 3) codes.unshift(codes[0]);

  return codes;
};

 还有一种方法是例如:(比较恶心的是它 市区都一样)

我是用的 VUE address-parse 地址解析,但它就是匹配不到以下四个市

       嘉峪关市 儋州市 中山市 东莞市

VUE address-parse 地址解析_woodFan先生的博客-优快云博客

所以重新考虑了一下用了新方法如下:

// 在需要调用的地方
export const filterateCity = function (data,arr,index = 0) {
  let result = []
  let resList = flatten(flatTree(data))
  if(index == 0) {
    resList.map(item => {
      if(arr.includes(item.name)) {
        result.push(item.code)
      }
    })
  } else  {
    resList.map(item => {
      if(arr.includes(item.code)) {
        result.push(item.name)
      }
    })
  }
  return result
}

// 获取新的数组数据
const flatten = (list, result = []) => {
  list.forEach(item => {
    result.push({
      code: item.code,
      name: item.fullname
    });
  });
  return result;
};

// 把树结构数据打平为一维数组
const flatTree = (treeData) => {
  let result = []
  treeData.forEach((item) => {
    // 先克隆一份数据作为第一层级的填充
    let res = JSON.parse(JSON.stringify(item))
    delete res.children
    result.push(res)
    if (item.children && item.children.length > 0) {
      // 如果当前children为数组并且长度大于0,才可进入flatTree()方法
      result = result.concat(flatTree(item.children))
    }
  })
  return result
}

在页面中如何调用呢?

// 例子:大概的思路,并不是完整的

// 比如目前是需要引用市区匹配不到的方法

<script>
   // 先把它们拎出来
   const areaList = ['东莞市', '中山市', '儋州市', '嘉峪关市']

   const [result] = AddressParse.parse(value); // 过滤的省市区和详情

   
   // 然后进行判断是否需要进入那个方法体
   if(areaList.includes(result.city || result.area)){
        
        filterateCity()
        // 一些逻辑...
   } else {
        getAreaByName()
        // 一些逻辑...
    }

</script>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值