obj类型的深层合并与展开

回到文章>>

COPYHTML

<div class="container"> <p>您可以在左右两边修改数据查看效果,请注意保证正确的结构</p> <p>分别点击两个按钮进行左右两个结构的转换</p> <div class="main"> <textarea id="data" rows="26" cols="40"></textarea> <div> <p><button id="flat-btn">转换 &gt;&gt;</button></p> <p><button id="parse-btn">&lt;&lt; 转换</button></p> </div> <textarea id="flated" rows="26" cols="40"></textarea> </div> <p id="error"></p> </div>

COPYCSS

.container { padding: 20px; } .main { display: flex; } .main p { margin: 0 20px; padding-top: 20px; }

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; }
新窗口打开