Skip to main content

实现一个对象的flatten

tip

考察编码能力,对递归js API的熟悉程度

一、题意

const obj = {
a: {
b: 1,
c: 2,
d: { e: 5 },
},
b: [1, 3, { a: 2, b: 3 }],
c: 3,
};

// flatten(obj) 结果返回如下
// {
// 'a.b': 1,
// 'a.c': 2,
// 'a.d.e': 5,
// 'b[0]': 1,
// 'b[1]': 3,
// 'b[2].a': 2,
// 'b[2].b': 3
// c: 3
// }

二、解法

function flatten(obj){
const result = {}; // 存放结果

innerFlatten(result, obj, '');

return result;

// 递归调用
function innerFlatten(store, oldObj, prevKey){
const objType = getType(oldObj);

if(objType == '[object object]'){
const keys = Object.keys(oldObj);
keys.forEach(key => {
const current = oldObj[key];
const newKey = getNewKey(prevKey, key);
if(typeof current !== 'object'){
store[newKey] = current;
}else{
innerFlatten(store, current, newKey)
}
});
return;
}

if(objType == '[object array]'){
for(let i = 0; i < oldObj.length; i++){
const current = oldObj[i];
const newKey = `${prevKey}[${i}]`;
if(typeof current !== 'object'){
store[newKey] = current;
}else{
innerFlatten(store, current, newKey)
}
}
return;
}
}

// 拼装新的key
function getNewKey(prevKey, nowKey){
if(prevKey.length < 1){
return nowKey;
}
return `${prevKey}.${nowKey}`;
}

// 获取对象类型
function getType(val){
return Object.prototype.toString.call(val).toLowerCase();
}
}