从一个地图数据结构延伸出对JS数组操作的一些思考

栏目: JavaScript · 发布时间: 5年前

内容简介:今天上午的时候正在兴致勃勃的写着bug,突然微信 “tututu~”的响了起来,点开一看,是一位前端新朋友给我发来的这样一个问题当时内心就是“这都什么年代了,还问这种数组问题,问我问题的标准线起码怎么说也要是三维空间中的二维图形的几何变换啊三大库的底层的源码的C是如何运行的啊之类的问题吧”,然后嘴上说着“小case”,手上回复着“马上就给你解决”。

今天上午的时候正在兴致勃勃的写着bug,突然微信 “tututu~”的响了起来,点开一看,是一位前端新朋友给我发来的这样一个问题

从一个地图数据结构延伸出对JS数组操作的一些思考

当时内心就是“这都什么年代了,还问这种数组问题,问我问题的标准线起码怎么说也要是三维空间中的二维图形的几何变换啊三大库的底层的源码的C是如何运行的啊之类的问题吧”,然后嘴上说着“小case”,手上回复着“马上就给你解决”。

他的数据结构是介样婶儿的:

var cityStr =[  { "name": "北京", "city": [{ "name": "北京", "area": ["东城区", "西城区"] }] },  { "name": "天津", "city": [{ "name": "天津", "area": ["和平区", "河东区"] }] },  { "name": "河北", "city": [{ "name": "石家庄", "area": ["长安区", "桥东区"] },                           { "name": "唐山", "area": ["路南区", "路北区"] },                          ]  }]复制代码

他的要求是:输入 “路南区”,能找到 它是在 “河北” -> “唐山” -> “路南区”。

其实看到这个要求,咱们肯定是想 “管他什么什么的,哥们儿都是一把梭,遍历遍历!”

当然哥们我也是一把梭走天下,不就是遍历嘛,嘴角疯狂上扬动,

for(let i = 0; i < cityStr.length; i++) {    for(let j = 0; j < cityStr['city'].length; j++) {        for(let k = 0; k < cityStr['city']['area'].length; k++) {            // 写到这里,嘴角的微笑逐渐凝固..        }    }}复制代码

卧槽,我已经晕了,梭不动了,层级套太多了,而且再来一层数组结构?那只能直接选择狗带了,不行,换一个,突然灵光一现,“不如来点更ES6的写法”,这是来自灵光界的一声暗呼。

说干就干,于是赶紧 command+a command+x ,空空的编辑器顿时就让我的呼吸也变得轻松了起来,写es6的诀窍就在于 “管他能不能写出来,先写一个function”,是的,写上 function filterFc() {} 的感觉像极了小学不会做的数学题但是写上了 “答:” 一样,舒畅~

function filterFc(address: string):any {
    return (这里要抛出address对应的父地点)
}复制代码

写到这里,心中顿时感觉 “成了!”抛出地点嘛,接下来,就是怎么抛地点出来。

怎么抛?又是一场遍历?不过既然要es6一点,那就不会再 for 了,es6的遍历多了,forEach, map, some, filter, find ... 哥如同后宫选妃侍寝一般,对数组api挑过来挑过去,不过逐渐意识到,好像能陪我走下去的它,并不是看上去那么多。

forEach?不行,它只能使用try...catch...进行中断,还不输出东西,宛如我要紫薇她确实容嬷嬷。

map?好像可以,抛出一个数组 [省,市,区] ,可以嘛,但是~,map也是无法中断的操作,那么找到了,还进行遍历好像是很没有必要的操作啊,就像吃了两碗牛肉面饱了了,你再喂我吃牛肉面?

filter?返回一个内部所有为true值的数据组成的数组,好像还是要面对吃牛肉面的问题...

find?返回第一个符合条件的牛肉面,进入视野 :heavy_check_mark:

some?返回布尔值,又是进入了我视野的牛肉面 :heavy_check_mark:

于是我就抠破了脑袋写下了:

var cityStr =    [        { "name": "北京", "city": [{ "name": "北京", "area": ["东城区", "西城区"] }] },        { "name": "天津", "city": [{ "name": "天津", "area": ["和平区", "河东区"] }] },        {            "name": "河北", "city": [{ "name": "石家庄", "area": ["长安区", "桥东区"] },                                    { "name": "唐山", "area": ["路南区", "路北区"] },                                    ]        }    ]
function filterFc(address: string):any {
    return cityStr.find((value:any, key: number, array: any[]): boolean => {
        return value['city'].some((v: any, k: number, arr: any[]): boolean => {
            return v['area'].some((ad: string, adKey: number): boolean => {
                return ad === address
            })
        })
    })
}复制代码

来分析一下为啥要这么写(简短分析,毕竟头顶凉嗖嗖的)

v['area'].some((ad: string, adKey: number): boolean => {
                return ad === address
})复制代码

通过 ‘ area ’ 字段比对输入区的名字在不在本 ‘area’ 里边,返回一个Boolean值,

value['city'].some((v: any, k: number, arr: any[]): boolean => {
            return v['area'].some((ad: string, adKey: number): boolean => {
                return ad === address
            })
})复制代码

抓住地区比对抛出的Boolean值,继续朝上抛出,这是同一步骤,最后

cityStr.find((value:any, key: number, array: any[]): boolean => {
        return value['city'].some((v: any, k: number, arr: any[]): boolean => {
            return v['area'].some((ad: string, adKey: number): boolean => {
                return ad === address
            })
        })
})复制代码

find函数能够用于找出第一个符合条件的数组成员,也就是说,只要你给我返回true,那么我就给你返回这条返回true的数据,这个API真是“像极了爱情”,正是我所需要的!函数 filterFc 返回那条满足我的数据!

测试一哈~

从一个地图数据结构延伸出对JS数组操作的一些思考

头皮发麻!盆友们,头皮发麻感受到了吗? 查 ‘路南区’,把河北下边的‘石家庄’、‘唐山’ 都给我了,可是我就想要 ‘河北’->‘唐山’->‘路南区’

改一下呗,‘还能离咋滴’...

于是成了:

var cityStr =    [        { "name": "北京", "city": [{ "name": "北京", "area": ["东城区", "西城区"] }] },        { "name": "天津", "city": [{ "name": "天津", "area": ["和平区", "河东区"] }] },        {            "name": "河北", "city": [{ "name": "石家庄", "area": ["长安区", "桥东区"] },            { "name": "唐山", "area": ["路南区", "路北区"] },            ]        }    ]
function filterFc(address: string):any {
    let ad = {},
        res = []

    let s = cityStr.some((value:any, key: number, array: any[]) => {
        if(
          value['city'].some((v: any, k: number, arr: any[]) => {                if (v['area'].includes(address)) {                    ad = arr[k]                    return true                }                            })        ) {
          res = [array[key]['name'], ad]
          return true
        }
    })
    
    if(s) {
        return res
    }
}复制代码

测试:

从一个地图数据结构延伸出对JS数组操作的一些思考

bingo~ 成功选好牛肉面!

PS: 其实写完后感觉,可以做的更通用一点,递归查找...有空试一试~~


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

实用Common Lisp编程

实用Common Lisp编程

Peter Seibel / 田春 / 人民邮电出版社 / 2011-10 / 89.00元

由塞贝尔编著的《实用Common Lisp编程》是一本不同寻常的Common Lisp入门书。《实用Common Lisp编程》首先从作者的学习经过及语言历史出发,随后用21个章节讲述了各种基础知识,主要包括:REPL及Common Lisp的各种实现、S-表达式、函数与变量、标准宏与自定义宏、数字与字符以及字符串、集合与向量、列表处理、文件与文件I/O处理、类、FORMAT格式、符号与包,等等。......一起来看看 《实用Common Lisp编程》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试