每天一道leetcode(Day 40)


格式转换

题目描述

给定一个“扁平”字典对象,其键是以点分割的。请实现一个函数,将其转换为”嵌套的”字典对象。

示例

输入:{'a':1,'b.a':2,'b.b':3,'c.d.e':4,'c.d'f':5}
输出:{
    'a':1,
    'b':{
        'a':2,
        'b':'3'
    },
    'c':{
        'd':{
            'e':4,
            'f':5
        }
    }
}

解题思路

  • 首先将原对象进行转换,以原对象的值为键,原对象的键用.切割后得到的数组为值,以示例中的对象为例,得到转换后的对象 tempObj,如下图所示:

image.png

  • 利用递归将 tempObj 还原成嵌套的对象:
    • 遍历 tempObj 中所有键值对,对每一个键值对调用 createObj 函数将其添加到最终的 res 中去
    • createObj 接受四个参数 obj-要添加的对象,arr-要添加的记录嵌套关系的 key 数组,index-当前处理到的 key 索引,val-要添加的值
    • 当 index=arr.length-1 时,表示已经处理到最深一层的属性,因此可以直接给 obj 添加相应的属性和值
    • 当 arr[index]这个属性在 obj 中不存在的话,说明这个属性是多重嵌套中间的属性,可以初始化这个属性,然后递归调用 createObj
    • 当 arr[index]这个属性存在的时候,直接进行下一次递归调用

代码

function convertObj(obj) {
  const tempObj = {};
  for (let key in obj) {
    tempObj[obj[key]] = key.split(".");
  }
  const res = {};
  for (let key in tempObj) {
    createObj(res, tempObj[key], 0, key);
  }
  return res;
}

function createObj(obj, arr, index, val) {
  if (index === arr.length - 1) {
    obj[arr[index]] = val;
  } else if (!obj[arr[index]]) {
    obj[arr[index]] = {};
    const i = index + 1;
    createObj(obj[arr[index]], arr, i, val);
  } else if (obj[arr[index]]) {
    const i = index + 1;
    createObj(obj[arr[index]], arr, i, val);
  }
}

测试结果:

const obj = {
  a: 1,
  "b.a": 2,
  "b.b": 3,
  "c.d.e": 4,
  "c.d.f": 5,
};
console.log(convertObj(obj));
// { a: '1', b: { a: '2', b: '3' }, c: { d: { e: '4', f: '5' } } }

文章作者: CassielLee
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 CassielLee !
评论
  目录