obj类型的深层合并与展开

回到文章
<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>
.container {
  padding: 20px;
}
.main {
  display: flex;
}
.main p {
  margin: 0 20px;
  padding-top: 20px;
}
// 收缩所有的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;
}