小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
1、扁平化对象
- 最近看到一个算法题,写出一个flatten函数将下列对象扁平。
const obj = {
a: 'a',
b: [1,2,{c:[1,2,3,4]},4],
c: { e: 5, f: 6 },
d: undefined,
f:[1,[1,2,[5,6]]]
};
//转换得到如下新数据结构:
const newobj = {
a: 'a',
'b[0]': 1,
'b[1]': 2,
'b[2].c[0]': 1,
'b[2].c[1]': 2,
'b[2].c[2]': 3,
'b[2].c[3]': 4,
'b[3]': 4,
'c.e': 5,
'c.f': 6,
d: undefined,
'f[0]': 1,
'f[1][0]': 1,
'f[1][1]': 2,
'f[1][2][0]': 5,
'f[1][2][1]': 6
}
首先我们看到这种数据结构去找他的转换规律,我们发现key:value
如果是一般对象,通过 .
一层一层的连接,如果是数组对象则通过[]
一层一层连接,而且每次到根节点,则在newobj
中新生成一条键值对,这是不是很像树的深度优先遍历? 其实这个就是将对象遍历和深度优先遍历结合起来,拼接key
值,直到根没有子节点返回的过程。
- 1、构造一个基本函数:
// 传入转换的对象
function flatten (obj){
// 构造一个目标对象
let newobj = {}
// 返回目标对象
return newobj
}
- 2、先不考虑
key:value
是数组情况,我们只考虑普通对象和基础数据类型。
// 传入转换的对象
function flatten (obj){
// 构造一个目标对象
let newobj = {}
//定义一个判断是否是对象的简单函数
function isobj (o){
return typeof o==='object'&&o!=null
}
//开始遍历转换对象
for(let key in obj){
// 如果是对象
if(isobj(obj[key])){
// 进一步遍历,直到不是对象
}else {
//不是对象择直接添加进我们的新对象
newobj[key] = obj[key]
}
}
// 返回目标对象
return newobj
}
- 3、额,写道这里好像有点问题,我们的遍历只有一层,下面如果还是对象就无法遍历了,这里应该使用深度优先遍历,我们重新构造一下。
// 传入转换的对象
function flatten (obj){
// 构造一个目标对象
let newobj = {}
//定义一个判断是否是对象的简单函数
function isobj (o){
return typeof o==='object'&&o!=null
}
// 定义一个深度优先遍历函数
let dsf = function(obj){
//开始遍历转换对象
for(let key in obj){
// 如果是对象
if(isobj(obj[key])){
// 进一步遍历,直到不是对象
dsf(obj[key])
}else {
//不是对象择直接添加进我们的新对象
newobj[key] = obj[key]
}
}
}
//开始遍历
dsf(obj)
// 返回目标对象
return newobj
}
- 4、我们已经遍历完了数据,接着就开始一层一层的拼接我们的新对象
key
值,在else
处我们会结束掉key
的拼接,开始新的拼接,注意:由于是一层一层拼接,每一层对象的key
值我们都会保留他上一层拼接的key
,所以这里我们需要将拼接的key
传递下去。
// 传入转换的对象
function flatten (obj){
// 构造一个目标对象
let newobj = {}
//定义一个判断是否是对象的简单函数
function isobj (o){
return typeof o==='object'&&o!=null
}
// 定义一个深度优先遍历函数
let dsf = function(obj,newkey){
//开始遍历转换对象
for(let key in obj){
//拼接当前key, newkey为空 就是第一次不拼接 .
let cur = newkey?`${newkey}.${key}`:key
// 如果是对象
if(isobj(obj[key])){
// 进一步遍历,直到不是对象
dsf(obj[key],cur)
}else {
//不是对象择直接添加进我们的新对象
newobj[cur] = obj[key]
}
}
}
//开始遍历
dsf(obj,'')
// 返回目标对象
return newobj
}
- 5、接下来吧对数组的判断加上,修改一下
cur
。
// 传入转换的对象
function flatten (obj){
// 构造一个目标对象
let newobj = {}
//定义一个判断是否是对象的简单函数
function isobj (o){
return typeof o==='object'&&o!=null
}
// 定义一个深度优先遍历函数
let dsf = function(obj,newkey){
//开始遍历转换对象
for(let key in obj){
//判断是不是数组
let isarr = Array.isArray(obj)
//拼接当前key, newkey为空 就是第一次不拼接 . []
let cur = newkey?(isarr?`${newkey}[${key}]`:`${newkey}.${key}`):`${key}`
// 如果是对象
if(isobj(obj[key])){
// 进一步遍历,直到不是对象
dsf(obj[key],cur)
}else {
//不是对象择直接添加进我们的新对象
newobj[cur] = obj[key]
}
}
}
//开始遍历
dsf(obj,'')
// 返回目标对象
return newobj
}
- 6、测试一下。
今天的文章[算法]一步步地将对象扁平化分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/22306.html