因为在开发中需要用到省市区数据,但是后端只返回最里层城市的code值
频繁百度找不到很好的方法,很多都是写了好几个方法去调用,并且多次调用导致很难理解;
这里分享一下我根据自己的思路所完成的一个方法。
(方法未经过长久测试,会有未知bug,并且可能会在不同数据体下也会有误差!)
废话:
在城市数据中我们知道,基本由以下三个字段构成:code、name、children
code是省市区的唯一代码,name则是省市区的名称,children则是省市区下的子项。
我们在只查找返回code对应的省市区的名称时很简单,普通的递归就可以实现;
但是如果我们也想要去获取上一层的数据,该怎么拿呢?
思路:
很简单,在递归中,除了第一层的循环,内循环均向下传入父级数据。
第一层循环不传入是因为如果不打断,就会卡死循环。
这个时候我们只能拿到两层数据,当前级和上一级。
那如果还想往上查找,还记得我们传入的父级数据吗,父级的code就起到了作用
重复调用递归方法,注意,此时调用必须传入源数据,也就是一开始的那一大串数据,这个时候调用查找到的就是父级的code和name
方法会一直循环遍历查询,直到已经达到最外层。
我们把我们所需要的数据用一个数组存放起来,并且return出去。
代码:
/**
* 根据code查询城市
* 并查出所有父级
* 原理 ===>
* 通过递归查找code与传入code相同
* 且在查找相同code的同时,将上级内容传递进下级循环中
* 如果code相同了,上级内容自然就能拿到
* 因为不知道有多少个上级
* 所以在查找到之后继续进行递归源数据(这里注意,并不是当前循环数据,而是最根本的数据)
* 这个时候不需要传递当前级的内容,否则无限循环卡死
*/
function getArea(json, code) {
let names = [];
let codes = [];
function findCity(list, code, father) {
const index = list.findIndex(ev => ev.code == code);
if (index > -1) {
const child = list[index];
names.unshift(child.name);
codes.unshift(child.code);
father && names.unshift(father.name) && codes.unshift(father.code);
father && findCity(json || [], father.code);
return;
}
list.map(item => {
if (item.children) {
findCity(item.children || [], code, item);
}
})
}
findCity(json, code);
names = [...new Set(names)];
codes = [...new Set(codes)];
return { codes, names };
}
const list = getArea(cityJson, parseInt(code));
console.log(list);