写在前面
已经好久没写文章了,距离上次写作过去差不多有一年的时间了,写作这东西真是太需要有耐心跟持久力啊。好记性不如烂笔头这句话真的很有见解,以前写过的东西不记录下来,随着时间的推移,真的会忘的一干二净,所以墙裂建议大家,对工作中遇到的知识点记录下来,以便以后随时查阅。
正文
记得当年做过这么一道高的面试题,今天刷题突然又碰上,于是就拿来解一解,里面的知识点确实不少。
这是后台返回的一堆数据,
按照要求进行输出:
-
将公交线路按照数字大小排序输出
-
将地铁线路按照数字大小排序输出
-
将其他线路按照字段长度进行排序输出
const res = {
code: 0,
data: {
lines: '20路,301路,5路,地铁15号线,地铁5号线,机场大巴线,107路,机场快轨',
lineids: 'lzbd,lwes,lxid,lwic,lwdf,ldfx,loin,loik',
linedetails: { lwdf: {
name: '机场大巴线'
},
lwes: {
name: '301路'
},
lwik: {
name: '地铁15号线'
},
lwic: {
name: '地铁5号线'
},
ldfx: {
name: '107路'
},
lzbd: {
name: '20路'
},
lxid: {
name: '5路'
},
loin: {
name: '机场快轨'
}
}
}}
乍一眼看上一头雾水啊,这可咋解。。。。。,冷静下来再次审题有了一点灵感,根据要求那不就是分类,然后在排序吗
梳理了下步骤:
1、拿到数据,将数据转化为数组
2、使用js高阶函数reduce进行循环
3、通过关键字 ‘路’、‘地铁’进行分类
4、最后对每个分类进行排序
上代码:
let data = res.data.linedetails
// 这里因为获取到的data是对象,
要使用reduce我们先用Object.entries将对象转化为数组
let dataArr = Object.entries(data) // 输出二维数组
let result = dataArr.reduce((pre, next) => {
// 获取到中文名字
let name = next[1].name
// 先查找公交线路
if(name.includes('路')) {
// 获取到公交线路的具体数字 -0利用隐式转换将字符串转化为数字
let number = name.slice(0, -1) - 0
// 用获取到的number作为键名进行存储,
//Object.fromEntries([next])将二位数组转换为对象
pre.bus[number] = Object.fromEntries([next])
}
else if (name.includes('地铁')){
// 这里利用正则进行匹配数字
let number = (next[1].name.match(/\d+/g))[0] - 0
pre.subway[number] = Object.fromEntries([next])
}
else{
let number = next[1].name.length
pre.other[number] = Object.fromEntries([next])
}
return pre
}, {
bus: {},
subway: {},
other: {}
})
console.log(result)
代码完毕,看一下打印结果,哇,成功了
到这基本上就已经是实现了要求了,有一个疑问啊,我是无序添加的每一类。为啥他就自动按key值的大小进行排序了呢?
这是因为浏览器在输出对象的时候,浏览器在输出的时候会调用js的方法中调用内部方法[[OwnPropertyKeys]]取得的key列表的顺序,类似于Object.keys方法的输出, 相当于浏览器替我们做了排序, Object的key遍历将会按:数字从小到大顺序进行遍历,也就是你看到的结果了。最后整理一下做最后的输出:
let { bus, subway, other } = result
let enties = [
...Object.values(bus),
...Object.values(subway),
...Object.values(other)
]
console.log(enties)
输出结果如下: 当然在输出完result之后,根据自己的需求进行结构调整
总结:
这道题里面包含了哪些知识点呢
1、对象与数组之间的转化
2、js的类型隐式转换
3、reduce高阶函数的妙用
4、查找字符串中的数字
5、浏览器对于key值的输出顺序