今天在刷面试题,看到了对象扁平化和数组扁平化,因此写这篇文章记录一下。
实现简单的对象扁平化
输入:
输出:
代码实现思路:我们可以利用Object.entries
获取对象的[key,value]
数组,遍历这个数组,进行进一步的判断(判断遍历的值的类型,如果是对象类型就递归调用,如果是普通类型就赋值给对象)。
function flat(item, preKey = "", res = {}) {
Object.entries(item).forEach(([key, val]) => {
if (val && typeof val === "object") {
flat(val, preKey + key + ".", res);
} else {
res[preKey + key] = val;
}
});
return res;
}
// 测试
const source = { a: { b: { c: 1, d: 2 }, e: 3 }, f: { g: 2 } };
console.log(flat(source));
实现复杂的对象扁平化
输入:
输出(注意,省略掉null):
代码实现思路:其实本质上就是多了一个遍历的obj的类型的判断和value的类型判断
const input = {
a: 1,
b: [1, 2, { c: true }, [3]],
d: { e: 2, f: 3 },
g: null,
};
function flat(obj = {}, preKey = "", res = {}) {
//空值判断,如果obj是空,直接返回
if(!obj) return
//获取obj对象的所有[key,value]数组并且遍历,forEach的箭头函数中用了解构
Object.entries(obj).forEach(([key,value])=>{
if(Array.isArray(value)){
//如果obj是数组,那么key就是数组的index,value就是对应的value
//obj是数组的话就用[]引起来
//因为value是数组,数组后面是直接跟元素的,不需要.号
let temp = Array.isArray(obj) ? `${preKey}[${key}]` : `${preKey}${key}`
flat(value,temp,res)
}else if(typeof value === 'object'){
//因为value是对象类型,所以在末尾需要加.号
let temp = Array.isArray(obj) ? `${preKey}[${key}].` : `${preKey}${key}.`
flat(value,temp,res)
}else{
let temp = Array.isArray(obj) ? `${preKey}[${key}]` : `${preKey}${key}`
res[temp] = value
}
})
return res;
}
console.log(flat(input));
实现数组扁平化
数组扁平化相较于对象扁平化更加简单
const arr = [1,2,[3,4,[5,6,[7,8,[9,0]]]]]
console.log(arr.toString().split(',').map(Number))
console.log(arr.flat(Infinity))
function flat (arr){
return arr.reduce((o,n)=>{
return o.concat(Array.isArray(n) ? flat(n) : n)
},[])
}
console.log(flat(arr))