Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
4.0k views
in Technique[技术] by (71.8m points)

根据省市区的汉字查找 对应code,如何优化?

现有这样的json数据

 {
      'value': '110000',
      'label': '北京市',
      'children': [
        {
          'value': '110100',
          'label': '北京市',
          'children': [
            {
              'value': '110101',
              'label': '东城区'
            },
            {
              'value': '110102',
              'label': '西城区'
            },
            {
              'value': '110105',
              'label': '朝阳区'
            },
            {
              'value': '110106',
              'label': '丰台区'
            },
            {
              'value': '110107',
              'label': '石景山区'
            },
            {
              'value': '110108',
              'label': '海淀区'
            },
            {
              'value': '110109',
              'label': '门头沟区'
            },
            {
              'value': '110111',
              'label': '房山区'
            },
            {
              'value': '110112',
              'label': '通州区'
            },
            {
              'value': '110113',
              'label': '顺义区'
            },
            {
              'value': '110114',
              'label': '昌平区'
            },
            {
              'value': '110115',
              'label': '大兴区'
            },
            {
              'value': '110116',
              'label': '怀柔区'
            },
            {
              'value': '110117',
              'label': '平谷区'
            },
            {
              'value': '110118',
              'label': '密云区'
            },
            {
              'value': '110119',
              'label': '延庆区'
            }
          ]
        }
      ]
    },
    {
      'value': '120000',
      'label': '天津市',
      'children': [
        {
          'value': '120100',
          'label': '天津市',
          'children': [
            {
              'value': '120101',
              'label': '和平区'
            },
            {
              'value': '120102',
              'label': '河东区'
            },
            {
              'value': '120103',
              'label': '河西区'
            },
            {
              'value': '120104',
              'label': '南开区'
            },
            {
              'value': '120105',
              'label': '河北区'
            },
            {
              'value': '120106',
              'label': '红桥区'
            },
            {
              'value': '120110',
              'label': '东丽区'
            },
            {
              'value': '120111',
              'label': '西青区'
            },
            {
              'value': '120112',
              'label': '津南区'
            },
            {
              'value': '120113',
              'label': '北辰区'
            },
            {
              'value': '120114',
              'label': '武清区'
            },
            {
              'value': '120115',
              'label': '宝坻区'
            },
            {
              'value': '120116',
              'label': '滨海新区'
            },
            {
              'value': '120117',
              'label': '宁河区'
            },
            {
              'value': '120118',
              'label': '静海区'
            },
            {
              'value': '120119',
              'label': '蓟州区'
            }
          ]
        }
      ]
    },

如何根据 ['北京市','北京市','东城区']
查出对应的code ["110000", "110100", "110101"]

先在的解决方案用的是三层遍历,有没有更优化的方法,求大神的优化防范

let findCodeByName = (areaList,province,city,area) =>{
            let data = [];
            areaList.forEach(pr => {
                if(pr.label === province) {
                    data.push(pr.value)
                    if(pr.children) {
                        pr.children.forEach(ci => {
                        if(ci.label === city) {
                            data.push(ci.value)
                            if(ci.children) {
                                ci.children.forEach( are => {
                                if(are.label === area) {
                                    data.push(are.value)
                                }
                            })
                        }
                        }
                    })
                }
                }
            });
            return data
        }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

我觉得你的数据应该不是完整的数据,顶层应该是一个数组对象,每个省是一个数据对象,即完整的应该是:

var AllData=[{...,'children':[{...,'children':[{},{}...]},{}...]},{}...]

即从顶层起,实质结构是类似的,可以分阶段遍历比较查询

你的查询用3层遍历是唯一可行的,不过你的代码没有注意安全性,没有考虑某些层没有匹配的情况。
如果不考虑空间占用,其实可以先对这些数据进行特殊化处理,比如转换成特殊的键值对数据集,就可以更快的查询,大致的意思是你可以重新把数据生成为键值对,比如

{"北京市":"110000",
 "北京市-北京市":"110100",
 "北京市-北京市-东城区":"110101",
 ....
 "天津市":"120000",
 "天津市-天津市":"120100",
 "天津市-天津市-和平区":"120101",
 ...
}

这样扁平化后查询就会很迅速。
而且这个数据其实也可以先由其他方法格式化好,查询起来更方便。

当然,这个只是一般性探讨,其实这样查询不一定有分层查询速度快的,可能只是感觉代码少一些而已。

此外,你可以利用lodash之类的库函数,它对这些查找有封装出来的工具,可以更方便的关注具体逻辑。比如引入Lodash后,相应的代码可能是:

let findXX=function( ArrLists,FindLists){
    let rt=[];
    let M=ArrLists;
    for(let i=0;i<FindLists.length;i++){
        let obj = _.find(M, {'label': FindLists[i] });
        if(obj==undefined) break;
        rt.push(obj['value'])
        M=(obj['children']?obj['children']:undefined)
        if(M==undefined) break;
    }
    return rt;
}
console.log(findXX(AllData,["北京市","北京市","da西城区"]))
console.log(findXX(AllData,["北京市","北京市","西城区"]))
console.log(findXX(AllData,["北京市"]))
console.log(findXX(AllData,["天津市","天津市"]))

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...