COPYJAVASCRIPT
// 收缩所有的key
function flat(param, parentKey = "") {
if (!param || typeof param !== "object") {
// 达到最深的一层
result[parentKey] = param;
return;
}
const isArray = Array.isArray(param);
result = isArray ? [] : {}; // 每次的递归都重新生成一个result
for (let key in param) {
const curKey = isArray ? `${parentKey}[${key}]` : `${parentKey}${parentKey === "" ? "" : "."}${key}`;
const item = param[key];
if (item && typeof item === "object") {
// 将当前的result与递归后返回的数据进行合并
result = { ...result, ...flat(item, curKey) };
} else {
result[curKey] = item;
}
}
return result;
};
// 展开所有的key
function parse(param) {
if (typeof param !== 'object') {
return param;
}
const result = Array.isArray(param) ? [] : {};
/**
* 获取这个key,因数组的key是用中括号[1]包括的,这里我们要获取中间的数字
* 若是纯英文字符串,则直接返回
* */
const getCurKey = (curKey) => {
return curKey.startsWith('[') ? curKey.match(/\d+/)[0] : curKey;
};
/**
* @param {string} key
* @param {any} val
* */
const setKey = (key, val) => {
const keyArr = key
.replace(/\[(\d+)\]/g, ($1, $2) => {
if ($1) {
return `.[${$2}]`;
}
return $1;
})
.split('.');
const { length } = keyArr;
let i = 0;
let obj = result;
// 当前key是什么类型,还要依赖下一个key才能判断,
// 如d.[0],说明d是一个数组;
// 若想是d.e这种结构,说明d是一个object;
while (i < length - 1) {
const isArray = keyArr[i + 1].startsWith('['); // 若下一个key是以`[`开头的,我们认为当前key是一个数组
const item = getCurKey(keyArr[i]);
if (!obj[item]) {
// 若这个key还没创建
obj[item] = isArray ? [] : {};
}
obj = obj[item];
i++;
}
// 最后的这个key不是不用创建结构的,仅用来赋值操作
// 如d[1] = 1, d['e'] = 2等
obj[getCurKey(keyArr[length - 1])] = val;
};
for (let key in param) {
setKey(key, param[key]);
}
return result;
}