解题进化路,还是自己太菜
/**
* 题目: 对象扁平化,不考虑环引用的情况
* 说明:请实现 flatten(input) 函数,input 为一个 javascript 对象(Object 或者 Array),返回值为扁平化后的结果。
* 示例:
* let input = {
* a: 1,
* b: [ 1, 2, { c: true }, [ 3 ] ],
* d: { e: 2, f: 3 },
* g: null,
* }
* let output = flatten(input);
* output如下
* {
* "a": 1,
* "b[0]": 1,
* "b[1]": 2,
* "b[2].c": true,
* "b[3][0]": 3,
* "d.e": 2,
* "d.f": 3,
* // "g": null, 值为null或者undefined,丢弃
* }
*/
解题进化过程
第一次
第一次(钻牛角尖了,看到题目是字符串形式的key,获取字符串key整个过程有点复杂了)
function flatten(input) {
let temp = input;
let result = {};
let keyArr = Object.getOwnPropertyNames(input);
keyArr.forEach((key) => {
// null undefined
if (temp[key] === "undefined" || Object.is(temp[key], null)) {
return;
} else if (typeof temp[key] === "object") {
// 数组、对象递归
if (Array.isArray(temp[key])) {
temp[key].forEach((item, index) => {
if (typeof item === "object") {
result = Object.assign(
{},
result,
flatten(
Object.defineProperty(
{},
key + "[" + index + "]",
{ value: item }
)
)
);
} else {
result['"' + key + "[" + index + ']"'] = item;
}
});
} else {
for (let childKey in temp[key]) {
if (typeof temp[key][childKey] === "object") {
result = Object.assign(
{},
result,
flatten(
Object.defineProperty(
{},
key + "." + childKey,
{ value: temp[key][childKey] }
)
)
);
} else {
result['"' + key + "." + childKey + '"'] =
temp[key][childKey];
}
}
}
} else {
// 普通类型
result['"' + key + '"'] = temp[key];
}
});
return result;
}
let input = {
a: 1,
b: [1, 2, { c: true }, [3]],
d: { e: 2, f: 3 },
g: null,
};
console.log("output1", flatten(input));
第二次
第二次,代码精简很多不考虑字符串的key,但是在外部引入一个全局变量result
let result = {};
function flatten(input) {
const temp = input;
const parentKey = Array.from(arguments)[1];
if (input instanceof Array) {
input.forEach((item, index) => {
if (typeof item === "object") {
flatten(item, `${parentKey}[${index}]`);
} else {
result[`${parentKey}[${index}]`] = flatten(
item,
`${parentKey}[${index}]`
);
}
});
} else if (input instanceof Object) {
for (let key in input) {
if (typeof input[key] === "object") {
if (parentKey) {
flatten(input[key], parentKey + "." + key);
} else {
flatten(input[key], key);
}
} else if (
input[key] === "undefined" ||
Object.is(input[key], null)
) {
continue;
} else {
if (parentKey) {
result[`${parentKey}.${key}`] = flatten(
input[key],
key
);
} else {
result[key] = flatten(input[key], key);
}
}
}
} else {
return input;
}
}
let input = {
a: 1,
b: [1, 2, { c: true }, [3]],
d: { e: 2, f: 3 },
g: null,
};
flatten(input)
console.log("output1", result);
第三次
第三次,(定义一个内部函数,这样就可以自定义新函数的入参)
function flatten(input) {
let result = {};
function flattenFn(input, parentKey) {
if (input instanceof Array) {
input.forEach((item, index) => {
if (typeof item === "object") {
flattenFn(item, `${parentKey}[${index}]`);
} else {
result[`${parentKey}[${index}]`] = flattenFn(
item,
`${parentKey}[${index}]`
);
}
});
} else if (input instanceof Object) {
for (let key in input) {
if (typeof input[key] === "object") {
if (parentKey) {
flattenFn(input[key], parentKey + "." + key);
} else {
flattenFn(input[key], key);
}
} else if (
input[key] === "undefined" ||
Object.is(input[key], null)
) {
continue;
} else {
if (parentKey) {
result[`${parentKey}.${key}`] = flattenFn(
input[key],
key
);
} else {
result[key] = flattenFn(input[key], key);
}
}
}
} else {
return input;
}
}
flattenFn(input);
return result;
}
let input = {
a: 1,
b: [1, 2, { c: true }, [3]],
d: { e: 2, f: 3 },
g: null,
};
console.log("output1", flatten(input));
第四次(最终版)
以为第三版本就是最终版了,没想到进一步抽离部分内容,代码还可以精简
function flatten(input) {
let result = {};
function flattenFn(obj, parentKey) {
if (obj instanceof Array) {
/**
* array遍历
* 引用类型执行递归
* 基础类型直接处理
*/
obj.forEach((item, index) => {
// 如果input直接就是数组,需要确认展开形式进一步增加判断
let newKey = parentKey + "[" + index + "]";
if (typeof item === "object") {
flattenFn(item, newKey);
} else {
result[newKey] = item;
}
});
} else if (obj instanceof Object) {
/**
* object遍历
* 引用类型执行递归
* null、undefined特殊处理
* 基础类型直接处理
*/
for (let key in obj) {
let value = obj[key];
let newKey = parentKey ? parentKey + "." + key : key;
if (typeof value === "object") {
flattenFn(value, newKey);
} else if (value === undefined || value === null) {
continue;
} else {
result[newKey] = value;
}
}
}
}
flattenFn(input);
return result;
}
另外,第三种方法也可以返回一个闭包函数,但是可能会调用两次函数(也可能我这边思路有问题hhh)