第 112 题:编程题,写个程序把 entry 转换成如下对象
yygmind opened this issue · comments
var entry = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae'
}
// 要求转换成如下对象
var output = {
a: {
b: {
c: {
dd: 'abcdd'
}
},
d: {
xx: 'adxx'
},
e: 'ae'
}
}
我继续先来
var entry = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae'
}
function map(entry) {
const obj = Object.create(null);
for (const key in entry) {
const keymap = key.split('.');
set(obj, keymap, entry[key])
}
return obj;
}
function set(obj, map, val) {
let tmp;
if (!obj[map[0]]) obj[map[0]] = Object.create(null);
tmp = obj[map[0]];
for (let i = 1; i < map.length; i++) {
if (!tmp[map[i]]) tmp[map[i]] = map.length - 1 === i ? val : Object.create(null);
tmp = tmp[map[i]];
}
}
console.log(map(entry));
题目
// 输入
var entry = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae'
};
// 要求转换成如下对象
var output = {
a: {
b: {
c: {
dd: 'abcdd'
}
},
d: {
xx: 'adxx'
},
e: 'ae'
}
};
实现思路
遍历对象,如果键名称含有 .
将最后一个子键拿出来,构成对象,如 {'a.b.c.dd': 'abcdd'}
变为 {'a.b.c': { dd: 'abcdd' }}
, 如果变换后的新父键名中仍还有点,递归进行以上操作即可。
// 输入
{
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae'
}
// 1
t1 = {
'a.b.c': { dd: 'abcdd' },
'a.d': { xx: 'adxx' },
a: { e: 'ae' }
};
// 2
// t1 = {
// 'a.b': { c: { { dd: 'abcdd' } },
// a: { d: { { xx: 'adxx' } },
// a: { e: 'ae' }
// };
// a.d 属性进行拆分时 需要新加入父键 a 而a已经存在 则进行合并
t2 = {
'a.b': { c: { dd: 'abcdd' } },
a: { e: 'ae', d: { xx: 'adxx' } }
};
// 3
// t3 = {
// 'a': { b: { c: { dd: 'abcdd' } } },
// a: { e: 'ae', d: { xx: 'adxx' } }
// };
t3 = {
a: { b: { c: { dd: 'abcdd' } }, e: 'ae', d: { xx: 'adxx' } }
};
代码
function nested(obj) {
Object.keys(obj).map(k => {
getNested(k);
});
return obj;
function getNested(key) {
const idx = key.lastIndexOf('.');
const value = obj[key];
if (idx !== -1) {
delete obj[key];
const mainKey = key.substring(0, idx);
const subKey = key.substr(idx + 1);
if (obj[mainKey] === undefined) {
obj[mainKey] = { [subKey]: value };
} else {
obj[mainKey][subKey] = value;
}
if (/\./.test(mainKey)) {
getNested(mainKey);
}
}
}
}
console.log(JSON.stringify(nested(entry), 0, 2));
const func2 = (input, output = {}) => {
const generateKeys = (key, value, output = {}) => {
const index = key.indexOf('.')
if (index > 0) {
const s = key.substring(0, index)
const e = key.substring(index + 1)
if (!output[s]) output[s] = {}
generateKeys(e, value, output[s])
} else {
output[key] = value
}
}
for (const k in input) {
generateKeys(k, input[k], output)
}
}
const o2 = {}
const input = func2(entry, o2)
console.log('o2', JSON.stringify(o2))
var entry = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae',
'd.e.x': 'dex'
}
const obj = {};
Object.keys(entry).map((keyName) => {
return keyName.split('.');
}).forEach(keysArr => {
let currObj = obj;
const keysArrLength = keysArr.length;
for (let i = 0; i < keysArrLength; i += 1) {
const keyItem = keysArr[i];
if (!currObj[keyItem]) {
currObj[keyItem] = i !== keysArrLength - 1 ? {} : entry[keysArr.join('.')];
}
currObj = currObj[keyItem];
}
});
console.log(obj);
var deFlat = function(entry) {
const res = {};
for (let key in entry) {
const sequenceKey = key.split('.');
format(res, sequenceKey, entry[key]);
}
return res;
}
var format = function(obj, sequenceKey, value) {
const key = sequenceKey.shift();
if (!sequenceKey.length) {
obj[key] = value;
} else {
obj[key] = obj[key] || {};
format(obj[key], sequenceKey, value);
}
}
var entry = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae'
}
console.log(deFlat(entry))
var entry = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae'
}
function setFlat (entry) {
let res = {}
function namespace(oNamespace, sPackage, value) {
let iner = oNamespace
let arr = sPackage.split('.')
let len = arr.length
arr.forEach((key, idx) => {
iner = iner[key] = (idx === len - 1 ? value : (iner[key] instanceof Object ? iner[key] : {}))
})
}
for (let k in entry) {
namespace(res, k, entry[k])
}
return res
}
console.log(JSON.stringify(setFlat(entry)))
// {"a":{"b":{"c":{"dd":"abcdd"}},"d":{"xx":"adxx"},"e":"ae"}}
var entry = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae'
}
function transObj(input) {
let ouput = null
let arr = Object.entries(input)
arr.forEach((item,index)=>{
let cellArr = item[0].split('.')
let cellObj = {}
let count = 0
while(cellArr.length) {
let key = cellArr.splice(-1)
if(count == 0) {
cellObj = {[key]:item[1]}
count ++
}else {
if(ouput && ouput[key]) {
ouput[key] = Object.assign(ouput[key],cellObj)
}else {
cellObj = {[key]:cellObj}
}
}
}
if(!ouput) {
ouput = cellObj
}
})
return ouput
}
console.log(transObj(entry))
实现思路:
- 对象entry的key中含有的
.
就是一个对象嵌套,所以可以用split()
函数将其划分为一个array,所以array的length - 1下标所对应的元素就是entry的一个key的具体值。 - 利用对象为地址引用原理,进行增加元素。
- 采用
reduce
函数,将每一次的引用返回。
const entry = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae',
};
const changObjStructureOfNormal = output => {
const keys = Object.keys(output);
const resObj = {};
for (const key of keys) {
const everyKey = key.split('.');
everyKey.reduce((pre, next, index, array) => {
if (index === array.length - 1) {
pre[next] = output[key];
return;
}
pre[next] = pre[next] || {};
return pre[next];
}, resObj);
}
return resObj;
};
changObjStructureOfNormal(entry);
function changeToNormal(obj) {
let newObj = {};
let t = newObj;
const keys = Object.keys(obj);
for (key of keys) {
const fArr = key.split('.');
while (fArr.length) {
const val = fArr.length === 1 ? entry[key] : {};
const tmpKey = fArr.shift();
t[tmpKey] = t[tmpKey] || val;
t = t[tmpKey];
}
t = newObj;
}
return newObj;
}
var entry = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae'
}
function getOutput(obj) {
let output = {};
if (Object.prototype.toString.call(entry) === '[object Object]') {
for (let i in obj) {
let splitKey = i.split('.');
(function getKeys(output, splitKey, value) {
const key = splitKey.shift();
if (!splitKey.length) {
output[key] = value;
} else {
output[key] = output[key] || {};
getKeys(output[key], splitKey, value)
}
})(output, splitKey, obj[i])
}
} else {
console.log('传入的不是对象');
}
return output;
}
getOutput(entry)
var entry = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae'
}
const tranfer = (o, r = {}) => {
for (let i in o) {
var a = i.split('.')
var j = 0
var stack = [{
parent: r,
key: a[j]
}]
while (stack.length) {
var item = stack.pop()
j ++
if (a[j]) {
if (!item.parent[item.key]) {
item.parent[item.key] = {}
}
stack.push({
parent: item.parent[item.key],
key: a[j]
})
} else {
item.parent[item.key] = o[i]
}
}
}
return r
}
var entry = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae'
}
function exchange(obj) {
if (typeof obj != 'object') {
throw new Error('请输入 [object Object] 类型')
}
// 对象转map
let map = new Map()
for (let key in obj) {
let arr = key.split('.')
map.set(arr, obj[key])
}
let O = {}
let digui = function(map, object) {
let obj = {}
map.forEach((item, index, arr) => {
// 取下标
let key = index.shift(),
length = index.length
// 判断是否存在,不存在就添加
if (!object[key]) {
object[key] = length > 0 ? obj : item //判断是否为最后一个key,如果是就展示值,不是就继续递归
}
if (length > 0) {
// 创建map结构
let currMap = new Map()
currMap.set(index, item)
digui(currMap, object[key])
}
})
}
digui(map, O)
return O
}
let res = exchange(entry)
console.log(res)
var entry = {
"a.b" : 111,
"a.c" : 2222,
"c.c" : 333,
"c.a.c": 3333
}
let obj = {
}
for(let [path , v] of Object.entries(entry)) {
let paths = path.split(".")
let k;
let cur = obj
// 最后一层路径
let tail = paths.pop()
// 迭代每层对象,在没有该路径情况下,创建,反之直接使用
while(k = paths.shift()) {
if(!cur[k]) {
cur[k] = {
}
}
// 切换到当前路径对象
cur = cur[k]
}
// 将值赋值给最终位置
cur[tail] = v
}
console.log(obj);
基本思路
我的思路:
- 遍历每一个需要展开的key,按照层级将其插入结果容器中。
- 首次出现的key则创建,重复出现则跳过,统一进入下一个层级。
- 当剩余展开深度为0则赋值
看到很多大神的回复,觉得有更好的思路可以实现,感觉自己这个比较普普通通哈哈。
/* 2019-07-24 */
var entry = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae'
}
var output = {
a: {
b: {
c: {
dd: 'abcdd'
}
},
d: {
xx: 'adxx'
},
e: 'ae'
}
}
// 要求将entry转化为output对象 (与昨日相反)
/* 解答 */
/**
*
* @param {Object} target 展开的key所插入的目标对象
* @param {Array} key 剩余需展开的key的数组
* @param {String} value 最终的值
*/
const transform = (target = {}, key = [], value = 0) => {
if (!key.length) return; // 终止递归
const currentKey = key.splice(0, 1); // 截取当前首位key
if (!target[currentKey]){
target[currentKey] = key.length=== 0 ? value : {} ; // 若当前属性为首次出现,则在对应深度创建该属性并赋值为空对象;若无剩余展开key时赋值
}
transform(target[currentKey], key, value); // 进入下一次递归
}
const result = {}; // 结果容器
const keys = Object.keys(entry); // 对象所需展开的字符串key
keys.map(item => transform(result, item.split('.'), entry[item]));
console.log(result);
var entry = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae'
}
let obj = {};
for (let key of Object.keys(entry)) {
key.split(".").reduce((s,c,i,a)=> {
s[c] = s[c] || (!a[i + 1] && entry[key]) || {};
return s[c];
}, obj);
}
console.log(JSON.stringify(obj));
var obj = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae'
}
function entery(obj){
let result = {}
Object.getOwnPropertyNames(obj).forEach(key=>{
getObj(key,obj[key],result)
})
function getObj(key,value,res){
console.log(res);
let keyArr = []
let _length;
keyArr = key.split('.');
_length = keyArr.length;
keyArr.forEach((item,index)=>{
if(index ==_length-1){
res[item] = value
}else {
res[item] = res[item] instanceof Object ? res[item]: {};
}
res = res[item];
})
}
return result;
}
console.log(entery(obj));
const transform = entry => {
const result = {};
for (let prop in entry) {
if (entry.hasOwnProperty(prop)) {
if (~prop.indexOf(".")) {
const arr = prop.split(".");
let curr = result;
while (arr.length > 1) {
const item = arr.shift();
if (!curr[item]) {
curr[item] = {};
}
curr = curr[item];
}
curr[arr.shift()] = entry[prop];
} else {
result[prop] = entry[prop];
}
}
}
return result;
};
实现
/** 将路径分解成数组 */
function pathToArray (path) {
return Array.isArray(path) ? path : path.replace(/\[/g, '.').replace(/\]/g, '').split('.')
}
/** 设置 object对象中对应 `path` 属性路径上的值 */
function set (object, path, value) {
path = pathToArray(path)
path.reduce((data, key, index) => {
if (index !== path.length - 1) {
if (!data[key]) { data[key] = {} }
} else {
data[key] = value
}
return data[key]
}, object)
}
测试
const entry = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae'
}
const output = {}
for (const [key, value] of Object.entries(entry)) {
set(output, key, value)
}
console.log(output)
var entry = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae'
};
function formatEntryToTree(obj) {
var output = {};
var handle = function(keys, value) {
keys.reduce(function(before, now, index) {
before[now] = index === keys.length - 1 ? value : output[now] || {};
return before[now];
}, output);
};
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
var keys = key.split('.');
handle(keys, obj[key]);
}
}
return output;
}
console.log(formatEntryToTree(entry));
var output = {}
var getObject = (data) => {
for (let [k, v] of Object.entries(entry)) {
let kList = k.split('.')
let evalStr = 'output'
kList.map((o, i) => {
if (kList.length - 1 === i) {
evalStr = evalStr + '.' + o
eval(`${evalStr}='${v}'`)
} else {
if(!output.hasOwnProperty(o)){
evalStr = evalStr + '.' + o
eval(`${evalStr}={}`)
}
}
})
}
}
getObject(entry)
console.log(output)
eval()大法实现,
function convert (obj) {
var returnObj = {};
for (var key in obj) {
var keyList = key.split('.');
if (!returnObj[keyList[0]]) {
returnObj[keyList[0]] = {};
}
var mapObj = returnObj[keyList[0]];
for (var i = 1; i < keyList.length; i++) {
var k = keyList[i];
if (i === keyList.length - 1) {
mapObj[k] = obj[key];
} else {
if (!mapObj[k]) {
mapObj[k] = {};
}
mapObj = mapObj[k];
}
}
}
return returnObj;
}
对象是引用类型的想法
const entry = { 'a.b.c.dd': 'abcdd', 'a.d.xx': 'adxx', 'a.e': 'ae', }; const changObjStructureOfNormal = output => { const keys = Object.keys(output); const resObj = {}; for (const key of keys) { const everyKey = key.split('.'); everyKey.reduce((pre, next, index, array) => { if (index === array.length - 1) { pre[next] = output[key]; return; } pre[next] = resObj[next] || {}; return pre[next]; }, resObj); } return resObj; }; changObjStructureOfNormal(entry);
pre[next] = resObj[next] || {};
错了,
const entry = {
'a.b.c.dd': 'abcdd',
'a.b.c.ee': 'abcee',
'a.d.xx': 'adxx',
'a.e': 'ae',
};
// output: {"a":{"b":{"c":{"ee":"abcee"}},"d":{"xx":"adxx"},"e":"ae"}}
// 'a.b.c.dd': 'abcdd' 被覆盖
pre[next] = resObj[next] || {};
应该改为 pre[next] = pre[next] || {};
const entry = { 'a.b.c.dd': 'abcdd', 'a.d.xx': 'adxx', 'a.e': 'ae', }; const changObjStructureOfNormal = output => { const keys = Object.keys(output); const resObj = {}; for (const key of keys) { const everyKey = key.split('.'); everyKey.reduce((pre, next, index, array) => { if (index === array.length - 1) { pre[next] = output[key]; return; } pre[next] = resObj[next] || {}; return pre[next]; }, resObj); } return resObj; }; changObjStructureOfNormal(entry);
pre[next] = resObj[next] || {};
错了,const entry = { 'a.b.c.dd': 'abcdd', 'a.b.c.ee': 'abcee', 'a.d.xx': 'adxx', 'a.e': 'ae', }; // output: {"a":{"b":{"c":{"ee":"abcee"}},"d":{"xx":"adxx"},"e":"ae"}} // 'a.b.c.dd': 'abcdd' 被覆盖
pre[next] = resObj[next] || {};
应该改为pre[next] = pre[next] || {};
哈哈,好像是错了,估计是粘贴变量名的时候粘错了位置。感谢提醒
function v(obj){
let arr = Object.keys(obj);
let $obj = {};
arr.map(key => {
let attrs = key.split('.');
attrs.reduce((str, v) => {
let s = `$obj.${str}`;
if(!eval(s)){eval(`${s}={}`);}
return str += '.' + v;
});
eval(`$obj.${key}=obj[key]`);
});
return $obj;
}
function transfer(entry) {
const result = {}
Object.entries(entry).forEach(([key, value]) => {
const keyArr = key.split('.');
result[keyArr[0]] = result[keyArr[0]] || {}
let targetObj = result[keyArr[0]]
for (let j = 1, length = keyArr.length; j < length; j++) {
if (j < length - 1) {
const tempObj = targetObj;
targetObj = targetObj[keyArr[j]] || {}
tempObj[keyArr[j]] = targetObj
} else {
targetObj[keyArr[j]] = value
}
}
})
return result;
}
function buildObj(obj) {
let result = {}
Object.keys(obj).forEach(key => {
let stack = key.split('.'),
res = result
while(stack.length !== 0) {
let k = stack.shift()
if (!res.hasOwnProperty(k))
res[k] = stack.length === 0 ? obj[key] : {}
res = res[k]
}
})
return result
}
//是不是也要考虑下值是别的类型的情况呀;比如是数组 number 之类的
var entry = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae',
'f.g':["a","b"]
}
console.log(transform(entry));
function transform(entry){
const target = {};
const map = new Map();
Object.keys(entry).forEach(key=>{
map.set(entry[key],key.split('.'));
})
map.forEach((vs,key)=>{
_transform(target,key);
})
return target;
function _transform(parent,key){
const k = map.get(key).shift();
if(!map.get(key).length){
parent[k] = key;
}else{
if(!parent[k]){
parent[k] = {};
}
_transform(parent[k],key);
}
}
}
const deepTree = obj => {
let res = {}
for (const [key, val] of Object.entries(obj)) {
let arr = key.split('.')
deep(res, arr, val)
}
function deep(obj, arr, val) {
let key = arr.shift()
if(key in obj){
deep(obj[key], arr, val)
}else if (arr.length > 0) {
obj[key] = {}
deep(obj[key], arr, val)
}else{
obj[key] = val
}
}
return res
}
let entry = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae',
'b.d.e.s.e':'bdese',
'a.v.d':'avd',
'b.d.e.b':'bdeb'
}
let ret = {}; //保存最终结果的对象。
function convert(option) {
for(var i in option) {
let value = option[i];
var keys = i.split(".")
convertKeys(keys, ret, value);
}
}
function convertKeys(keys, ret, value) {
for(let i in keys) {
let key = keys[i];
let index = i;
if(!ret[key]) {
ret[key] = {};
}
if(keys.slice(index + 1).length > 0) {
convertKeys(keys.slice(index +1), ret[key], value);
} else { // 说明已经遍历到最后一个key, 不需要继续遍历了,直接赋值。
ret[key] = value;
}
break;
}
}
convert(entry);
console.log(ret); //{"a":{"b":{"c":{"dd":"abcdd"}},"d":{"xx":"adxx"},"e":"ae","v":{"d":"avd"}},"b":{"d":{"e":{"s":{"e":"bdese"},"b":"bdeb"}}}}
function fnOutput(obj){
let newObj = {}
for(let key in obj){
let nameArr = key.split('.')
nameArr.reduce((pre,item,i)=>(pre[item]= i===nameArr.length-1 ? obj[key] : (pre[item] || {}) ,pre[item]),newObj)
}
return newObj
}
const expendObj = (obj) => {
var arr = [];
var arr2 = [];
for (key in obj) {
arr.push(key.split("."))
arr2.push(obj[key])
}
var res = {};
arr.reduce((obj1, c, j) => {
c.reduce((obj2, curr, i) => {
obj2[curr] = obj2[curr] || {}
if (i === c.length - 1) {
obj2[curr] = arr2[j]
}
return obj2[curr]
}, obj1)
return res
}, res)
return res
}
console.log(expendObj(entry))
var entry = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae'
}
function fn (node) {
let path, pathArr, i, len, obj, key;
let res = {};
for (path in node) {
obj = res;
pathArr = path.split('.');
for (i = 0, len = pathArr.length - 1; i < len; i++) {
key = pathArr[i];
obj = obj[key] = obj[key] || {};
}
obj[pathArr[len]] = node[path];
}
return res;
}
console.log( JSON.stringify(fn(entry)) );
var entry = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae',
'text': 'text'
}
function go(obj,res) {
for(key in obj){
let arr = key.split('.');
if(arr.length > 1){
res[arr[0]] = res[arr[0]] || {};
let cur = res[arr[0]];
for(let i = 1;i<arr.length;i++){
if(i === arr.length -1){
cur[arr[i]] = obj[key]
}else{
if(!cur[arr[i]]){
cur[arr[i]] = {};
}
cur = cur[arr[i]];
}
}
}else{
res[arr[0]] = obj[key]
}
}
return res;
}
console.log(go(entry,{}))
我继续先来
var entry = { 'a.b.c.dd': 'abcdd', 'a.d.xx': 'adxx', 'a.e': 'ae' } function map(entry) { const obj = Object.create(null); for (const key in entry) { const keymap = key.split('.'); set(obj, keymap, entry[key]) } return obj; } function set(obj, map, val) { let tmp; if (!obj[map[0]]) obj[map[0]] = Object.create(null); tmp = obj[map[0]]; for (let i = 1; i < map.length; i++) { if (!tmp[map[i]]) tmp[map[i]] = map.length - 1 === i ? val : Object.create(null); tmp = tmp[map[i]]; } } console.log(map(entry));
当出现没有点的时候如下:
var entry = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae',
"f": "12345"
}
会出问题,因此在set里面要再做一层判断如下就更好了:
function set(obj, map, val) {
if(map.length === 1){
return obj[map[0]] = val
}
if(!obj[map[0]]) obj[map[0]] = Object.create(null)
let temp = obj[map[0]]
for(let i = 1;i< map.length;i++){
if(!temp[map[i]]) temp[map[i]] = i === map.length -1?val: Object.create(null)
temp = temp[map[i]]
}
}
const res = {};
const entry = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae'
};
for (let key in entry) {
setKeypath(res, key, entry[key]);
}
function setKeypath(obj, keypath, value) {
const keypaths = keypath.split(".")
let key
let lastKeyvalue = obj
while (key = keypaths.shift()) {
const keyvalue = lastKeyvalue[key] || {}
lastKeyvalue[key] = keypaths.length ? keyvalue : value
lastKeyvalue = keyvalue
}
return obj
}
function forMate(entry) {
let res = {};
Object.keys(entry).forEach(key => {
key.split('.').reduce((pre, cur, index, arr) => {
if (!pre[cur] && index !== arr.length - 1) {
pre[cur] = {};
return pre[cur];
} else if (pre[cur] && index !== arr.length - 1) {
return pre[cur];
} else {
pre[cur] = entry[key];
return res;
}
}, res)
});
return res;
}
function switchObj(obj, result={}){
for(var key in obj){
~key.indexOf('.') ? key.split('.').reduce((r, item, index, arr) => {
if(index === arr.length - 1){
r[item] = obj[key]
return
}
r[item] = r[item] || {}
return r[item]
}, result ) : result[key] = result[key] || obj[key]
}
return result
}
看你们随随便便就写出来了,我光是理解就要好久。。。
function getOO(obj) {
var keys = Object.keys(obj)
var res = {}
var setfunc = (keyArr, res, val) => {
// if (!res[keyArr[0]]) { res[keyArr[0]] = {} }
if (keyArr.length > 1) {
let k = keyArr.shift()
res[k] = res[k] || {}
setfunc(keyArr, res[k], val)
} else {
res[keyArr[0]] = val
}
}
for (let key of keys) {
let keyArr = key.split('.')
//[a, b, c, dd] [a, d, xx] [a, e]
setfunc(keyArr, res, obj[key])
}
console.log(res, 'resss')
return res
}
getOO({
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae'
})
var exchangEntry = function (data) {
var obj = {};
for (var k in data) {
var arr = k.split('.');
var lastObj = obj;
var j = void 0;
while (j = arr.shift(), arr.length) {
lastObj = lastObj[j] || (lastObj[j] = {});
}
lastObj[j] = data[k];
}
return obj;
};
递归函数即可
function reverseChange(obj) {
const output = {}
function giveProps(targetObj,props,index = 0) {
if(index !== props.length - 1) {
if(!targetObj[props[index]]) {
targetObj[props[index]] = {}
giveProps(targetObj[props[index]],props,++index)
} else {
giveProps(targetObj[props[index]],props,++index)
}
} else {
console.log(targetObj[props[index]])
console.log(props[index])
targetObj[props[index]] = obj[props.join('.')]
}
}
for(let k in obj) {
const props = k.split('.')
giveProps(output,props)
}
return output
}
var entry = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae'
}
console.log(reverseChange(entry))
和一楼大佬思路一样
var entry = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae',
'b.e':'cc',
}
doSth(entry)
function doSth(obj){
let output = {}
for (const key in obj) {
console.log(key,obj[key]);
let arr = key.split('.')
if (!output[arr[0]]){
output[arr[0]] = Object.create(null)
}
// output.a
let moreObj = output[arr[0]]
for (let i = 1; i < arr.length; i++) {
//arr[i]:b,c,dd
if (i == arr.length -1){
moreObj[arr[i]] = obj[key]
} else {
moreObj[arr[i]] = Object.create(null)
}
// 取下一层a.b
moreObj = moreObj[arr[i]]
}
}
console.log(output);
}
不喜欢递归。
function expand (obj) {
var keys = Object.keys(obj)
var map = {}
while (keys.length) {
var current = keys.shift()
var key = current.split('.')
var tmp = {}
for (var i = key.length - 1; i >= 0; i--) {
if (i === key.length - 1) {
tmp[key[i]] = obj[current]
} else {
tmp[key[i]] = {
[key[i + 1]]: tmp[key[i + 1]]
}
delete tmp[key[i + 1]]
}
if (i === 0) {
var k = Object.keys(map)
if (key[0] === k[0]) {
map[key[0]] = Object.assign(map[key[0]], tmp[key[0]])
} else {
map = Object.assign(map, tmp)
tmp = {}
}
}
}
}
return map
}
分治版本
思路是遍历对象的每个属性,分别生成一个对象,然后将所有对象合并起来。
function spread(obj){
//分别处理每个属性
function toObj(key,value) {
let obj = {};
if(key.indexOf('.') !== -1){
let temp = key.split('.');
obj[temp[0]] = toObj(temp.slice(1).join('.'),value);
}else {
obj[key] = value
}
return obj;
}
//合并所有属性对象
function assign(ori,tar){
for(let key in ori){
if(ori.hasOwnProperty(key) && tar.hasOwnProperty(key)){
ori[key] = assign(ori[key],tar[key])
}
}
return typeof ori === 'object' ? Object.assign(tar,ori) : ori;
}
let ans = {};
for(let key in obj){
if(obj.hasOwnProperty(key)){
assign(toObj(key,obj[key]),ans)
}
}
return ans;
}
function spread(input) {
let entry = {};
Object.keys(input).forEach(keys => {
let prev = entry;
let dots = keys.split('.');
for (let i = 0; i < dots.length - 1; i++) {
prev = prev[dots[i]] = prev[dots[i]] || {};
}
prev[dots[dots.length - 1]] = input[keys];
});
return entry;
}
function convert(data) {
return Object.keys(data).reduce((res, keys) => {
const value = data[keys];
const keyList = keys.split(".");
const lastKey = keyList.pop();
const objResult = keyList.reduce((obj, key) => {
if (!obj[key]) {
obj[key] = {};
}
return obj[key];
}, res);
objResult[lastKey] = value;
return res;
}, {});
}
var trans_obj = {
"a.b.c.dd": "abcdd",
"a.d.xx": "adxx",
"a.e": "ae",
"b": 1,
}
var entry1 = trans1(trans_obj);
console.log('entry1: ', entry1);
function trans1(obj) {
var res = {};
for (var [k, v] of Object.entries(obj)) {
var arr = k.split('.');
set(res, arr, v);
}
function set(obj1, keys, val) {
if (keys.length > 1) {
var key = keys.shift();
if (!obj1[key]) {
obj1[key] = {};
}
set(obj1[key], keys, val);
} else {
obj1[keys.shift()] = val;
}
}
return res;
}
var entry = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae'
}
// 要求转换成如下对象
var output = {
a: {
b: {
c: {
dd: 'abcdd'
}
},
d: {
xx: 'adxx'
},
e: 'ae'
}
}
function transform (entry = {}) {
const res = {}
for (let key in entry) {
if (entry.hasOwnProperty(key)) {
next(key, entry[key], res)
}
}
return res
}
function next (key, val, res) {
let temp = res
const arr = key.split('.')
const len = arr.length
for (let i = 0; i < len; i++) {
const item = arr[i]
if (!temp[item]) {
temp[item] = i === len - 1 ? val : {}
}
temp = temp[item]
}
}
console.log(transform(entry))
采用递归进行设置值,可能是比较清晰的一个方法了
function nested(obj){
let result = {}
Object.keys(aa).forEach(key=>{
keyArrays = key.split('.')
ObjectSet(result, keyArrays, obj[key])
})
function ObjectSet(o, keys, data){
const key = keys.shift()
if(keys.length===0){
o[key] = data
}else{
if(typeof o[key] === 'undefined'){
o[key] = {}
}
ObjectSet(o[key], keys, data)
}
}
return result
}
const getEntry = (entry)=>{
var out = {};
for(let e in entry){
let arr = e.split(".");
arr.reduce((t,v,n)=>{
n != arr.length-1 ? (t[v] ? t[v] : t[v] = {}) : t[v]=entry[e];
return t[v];
},out);
}
return out;
};
var entry = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae'
}
function change(entry, res = {}){
function setRes(obj, keyArr, val){
let key = keyArr.shift()
if(keyArr.length == 0){
obj[key] = val
}else{
if(obj[key] === undefined){
obj[key] = {}
setRes(obj[key], keyArr, val)
}else{
setRes(obj[key], keyArr, val)
}
}
}
for(let key in entry){
let val = entry[key]
let keyArr = key.split('.')
setRes(res, keyArr, val)
}
return res
}
console.log(change(entry))
const translate = obj => {
const res = {}
Object.keys(obj).forEach(key => {
const keyArr = key.split('.')
// let temp
// keyArr.forEach((k, i) => {
// if (i == 0) { // 顶层属性
// res[k] = res[k] || {}
// temp = res[k]
// } else if (i === keyArr.length-1) { // 末层属性
// temp[k] = obj[key]
// } else { // 中间层的属性
// temp[k] = temp[k] || {}
// temp = temp[k]
// }
// })
keyArr.reduce((a, b, i) => {
if (i === keyArr.length-1) {
a[b] = obj[key]
} else {
a[b] = a[b] || {}
}
return a[b]
}, res)
})
return res
}
function trans(obj) {
let res = {}
let temp
for (let key in obj) {
temp = res
let arr = key.split('.')
let len = arr.length
for (let i = 0; i < len - 1; i++) {
if (!temp[arr[i]]) {
temp[arr[i]] = {}
}
temp = temp[arr[i]]
}
temp[arr[len - 1]] = obj[key]
}
return res
}
function parseToObj(obj) {
return Object.keys(obj).reduce((res, path) => {
const keys = path.split('.')
const deepestObj = keys.slice(0, -1).reduce((o, key) => {
o[key] = o[key] || {}
return o[key]
}, res)
deepestObj[keys[keys.length - 1]] = obj[path]
return res
}, {})
}
const testObj = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae'
}
console.log(parseToObj(testObj))
const entry2normal = (input: { [key: string]: string }) => {
const result: { [key: string]: any } = {};
const translator = (
[key, ...resKeys]: string[],
value: string,
parent = result
) => {
if (!resKeys.length) {
parent[key[0]] = value;
return;
}
if (!parent[key] || typeof parent[key] === 'string') parent[key] = {};
translator(resKeys, value, parent[key]);
};
Object.entries(input).forEach(([key, value]) => {
translator(key.split('.'), value);
});
return result;
};
有点像链表
var entry = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae'
}
const search = (keys, res, value) => {
let cur = res
for (let i = 0; i < keys.length; i++) {
if (i === keys.length - 1) {
cur[keys[i]] = value
} else if (!cur[keys[i]]) {
cur[keys[i]] = {}
cur = cur[keys[i]]
}
}
}
const solution = (obj) => {
let res = {}
for (let i in obj) {
let keys = i.split('.')
search(keys, res, obj[i])
}
return res
}
console.log(solution(entry))
function convert(entry) {
let obj = {};
for (const key in entry) {
if (entry.hasOwnProperty(key)) {
let keys = key.split(".");
// keys只有一个时直接赋值
if (keys.length === 1) {
obj[keys[0]] = entry[key];
continue
}
if (!obj[keys[0]]) {
obj[keys[0]] = Object.create(null);
}
// 储存对象最深属性的引用地址
let temp;
temp = obj[keys[0]];
for (let i = 1; i < keys.length; i++) {
if (i === keys.length - 1) {
temp[keys[i]] = entry[key];
} else {
temp[keys[i]] = Object.create(null);
temp = temp[keys[i]];
}
}
}
}
return obj;
}
function translateEntery(entry) {
const returnValue = {}
if(typeof entry == 'object') {
Object.keys(entry).forEach(key => {
if(key.includes('.')) {
const arr = key.split('.')
generate(returnValue, arr, entry[key])
}
})
}
function generate(returnValue, arr, value) {
if(arr.length == 1) {
returnValue[arr.shift()] = value
return
}
const key = arr.shift();
!returnValue[key] && (returnValue[key] = {});
return generate(returnValue[key], arr, value)
}
return returnValue
}
const convert = function (obj) {
const ans = {};
function helper(o, prefix) {
if (!o) {
return;
}
Object.keys(o).forEach(k => {
const v = o[k];
const p = prefix ? `${prefix}.${k}` : k;
switch (typeof v) {
case 'string':
case 'number':
case 'boolean':
case 'undefined':
ans[p] = v;
break;
default:
helper(v, p);
break;
}
});
}
helper(obj, null);
return ans;
};
var entry = {
a: {
b: {
c: {
dd: 'abcdd'
}
},
d: {
xx: 'adxx'
},
e: 'ae'
}
};
console.log(convert(entry));
// {
// 'a.b.c.dd': 'abcdd',
// 'a.d.xx': 'adxx',
// 'a.e': 'ae'
// };
function format(entry) {
const result = {}
Object.keys(entry).forEach((keyDot) => {
const keys = keyDot.split(".");
const value = entry[keyDot];
let tmp=result;
while (keys.length) {
const key = keys.shift()
if (keys.length === 0) {
tmp[key] = value
} else {
tmp[key] = tmp[key] || {}
tmp = tmp[key];
}
}
})
return result
}
// 要求转换成如下对象
var entry = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae'
};
console.log("debug-", format(entry));
function objTransitionStr(output) {
const keySplit = Object.keys(output).map((key) => key.split("."));
const values = Object.values(output);
const res = {};
keySplit.forEach((keys, i) => {
keys.reduce((res, key, index) => {
if (index === keys.length - 1) {
res[key] = values[i];
}
return key in res ? res[key] : (res[key] = {});
}, res);
});
return res;
}
var output = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae'
}
const find09 = (val) => {
let obj = {}
for (let key in val) {
let keys = key.split('.')
let bb = obj
keys.forEach((item, index) => {
if (!bb[item]) {
bb[item] = index !== keys.length - 1 ? {} : val[key];
bb = bb[item]
}
})
}
}
find09(output)
var entry = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae'
}
function gen(data){
const obj = {} // 创建空对象
Object.entries(data).forEach(([keys,val])=>{
// 获取key 和 value
let now = obj // 保存读取到的路径
const path = keys.split('.') // 切割keys变成路径
const key = path.pop() // 弹出最后一个路径用来赋值
path.forEach(key =>{ // 遍历路径创建
if(!(key in now)){ // 如果路径不存在那么创建一个路径
now[key] = {}
}
now = now[key] // 进入路径
})
now[key] = val // 给最终路径赋值
})
return obj
}
console.log(gen(entry))
根据 x.y.z
来迭代
var entry = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae'
}
function transformReverse(entry) {
const output = {};
Reflect.ownKeys(entry).forEach(key => {
const val = entry[key];
const keySplitByDot = key.split('.');
let temp = output;
while (keySplitByDot.length > 0) {
const attr = keySplitByDot.shift();
if (keySplitByDot.length === 0) {
temp[attr] = val;
} else {
if (!temp[attr]) {
temp[attr] = {};
}
temp = temp[attr];
}
}
});
console.log(output);
return output;
}
transformReverse(entry)
1、使用一个额外的变量 preObj 来实现
function transform(obj) {
var res = {}
var preObj = res
Reflect.ownKeys(obj).forEach((key) => {
var keys = key.split('.')
keys.forEach((v, i) => {
if (i === keys.length - 1) {
// 已达最后一个键值,赋值
preObj[v] = obj[key]
// 重置 preObj
preObj = res
} else {
// 当前 key 已存在,则取值,否则创建新对象
preObj[v] = preObj[v] || {}
// 改变 preObj 指向,实现链式调用
preObj = preObj[v]
}
})
})
return res
}
2、使用 reduce 简化
function transform(obj) {
var res = {}
Reflect.ownKeys(obj).forEach((key) => {
var keys = key.split('.')
keys.reduce((pre, cur, i) => {
if(i === keys.length - 1) {
pre[cur] = obj[key]
} else {
pre[cur] = pre[cur] || {}
pre = pre[cur]
}
return pre
}, res)
})
return res
}
// 测试
var entry = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae',
k: 'k',
}
transform(entry)
const entry = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae',
'a.e.f': 'cover',
'd.x': 'dx',
'd': 'cover-d'
};
function format(entry) {
const result = Object.create(null);
for (let [key, val] of Object.entries(entry)) {
const keys = key.split('.');
set(keys.splice(0, 1)[0], keys.reduceRight((pre, k) => ({ [k]: pre }), val), result);
}
return result;
}
function set(key, val, obj) {
// 基础类型的值的话就做覆盖操作
(typeof obj[key] !== 'object' || typeof val !== 'object') && (obj[key] = val, true)
|| Object.entries(val).forEach(([k, v]) => set(k, v, obj[key]));
}
const result = format(entry);
console.log(JSON.stringify(result))
// 前缀树
const entryToTree = (entry: Dict<string>) => {
const res = { root: {} } as Record<string, any>
const pathes: string[][] = []
for (const [k, v] of Object.entries(entry)) {
pathes.push([...k.split('.'), v])
}
for (const path of pathes) {
let root = res.root
const key = path[path.length - 2]
const value = path[path.length - 1]
for (let i = 0; i < path.length - 2; i++) {
const char = path[i]
if (!Object.keys(root).includes(char)) root[char] = {}
root = root[char]
}
root[key] = value
}
return res.root
}
### const find77 = (entry) => {
let map = {}
for (key in entry) {
let m = key.split('.');
let n = map;
m.forEach((item, index) => {
if (!n[item]) {
n[item] = index !== m.length - 1 ? {} : entry[key]
n = n[item]
}
})
}
}
function transform(obj) {
let ret = {}
function mergeObj(o1, o2) {
Object.keys(o2).forEach(key => {
if (key in o1) {
o1[key] = mergeObj(o1[key], o2[key])
} else {
o1[key] = o2[key]
}
})
return o1
}
Object.keys(obj).forEach(key => {
let keyArr = key.split('.').reverse()
let o = keyArr.reduce((pre, curKey) => {
return {
[curKey]: pre
}
}, obj[key])
ret = mergeObj(ret, o)
})
console.log(ret.a.b.c)
}
var entry = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae'
}
transform(entry)
var deFlatten = function (entry) {
const res = {};
var format = (res, keys, value) => {
const key = keys.shift();
if (!keys.length) {
res[key] = value;
} else {
res[key] = res[key] || {};
format(res[key], keys, value);
}
};
for (const key in entry) {
const keys = key.split('.');
format(res, keys, entry[key]);
}
for (const key in res) {
if (/^\w+\[\d+\]$/.test(key)) {
const k = key.match(/^\w+/)[0];
const i = key.match(/[\d+]/g).join('');
res[k] = res[k] || [];
res[k][i] = res[key];
delete res[key];
}
}
return res;
}
deFlatten({
"a.b": 1,
"a.c": 2,
"asss.d.e": 5,
"baa[0]": 1,
"b[1]": 3,
"b[2].a": 2,
"b[20].b": 3,
"c": 3
})
var entry2 = {
"a.b.c.dd": "abcdd",
"a.d.xx": "adxx",
"a.e": "ae",
"a.d.xy": "ae",
};
function foo(input) {
const result = {};
Object.entries(input).forEach(([k, v]) => {
const keys = k.split(".");
keys.reduce((acc, key, index) => {
if (typeof acc[key] === "undefined") {
acc[key] = Object.create(null);
}
if (index === keys.length - 1) {
acc[key] = v;
}
return acc[key];
}, result);
});
return result;
}
思路
- 以"."将key分割成数组
- 声明变量temp,利用js对象指向同一个引用地址的特性,把上一次的结果带进下一次循环中
- length - 1为得到value的终止条件
var entry = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae',
}
/**
* 转换
* @author waldon
* @date 2022-04-11
* @param {*} entry - param
*/
function translateEntry(entry) {
const res = {}
for (const key of Object.keys(entry)) {
const keyArr = key.split('.')
const value = entry[key]
let temp = res
for (let i = 0, len = keyArr.length; i < len; i++) {
const subKey = keyArr[i]
if (i === keyArr.length - 1) {
temp[subKey] = value
} else {
temp[subKey] = temp[subKey] || {}
temp = temp[subKey]
}
}
}
return res
}
console.log(translateEntry(entry))
思路
- 1 利用reduce写法, 将key转化为嵌套对象, 因为对象指向的是内存地址,会同步更新
- 2 当到数组的最后一个值时,说明不再是对象,赋值即可
`
/**
* 1 利用reduce写法, 将key转化为嵌套对象, 因为对象指向的是内存地址,会同步更新
* 2 当到数组的最后一个值时,说明不再是对象,赋值即可
* @param {*} obj
* @returns
*/
function transform (obj) {
const result = {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
if (key.indexOf('.') > -1) {
const arr = key.split('.');
arr.reduce((pre, cur, index) => {
pre[cur] = pre[cur] || {};
if (index === arr.length - 1) { // 赋值
pre[cur] = obj[key];
}
return pre[cur];
}, result)
} else {
result[key] = obj[key];
}
}
}
return result
}
`
var entry = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae'
}
function trans(obj) {
const res = {}
for (let key in obj) {
let target = res
const path = key.split('.')
for (let i = 0, l = path.length - 1; i < l; i++) {
target = (target[path[i]] = target[path[i]] || {})
}
target[path[path.length - 1]] = obj[key]
}
return res
}
function test(obj) {
const res = {}
for (const keys in obj) {
const keyList = keys.split('.')
const len = keyList.length
const loop = (target, i) => {
const key = keyList[i]
if (i < len - 1) {
loop(target[key] || (target[key] = {}), i + 1)
} else {
target[key] = obj[keys]
}
}
loop(res, 0)
}
return res
}
function convert(obj) {
const result = {};
for (let k of Object.keys(obj)) {
const paths = k.split('.');
paths.reduce((ac, cur, idx) => {
if (!ac[cur]) {
if (idx === arr.length - 1) {
ac[cur] = obj[k];
} else {
ac[cur] = {};
}
}
return ac[cur];
}, result)
}
return result;
}
const entry = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae'
};
function cook(obj) {
let res = {};
Object.keys(obj).forEach(keyPath => {
const value = obj[keyPath];
const list = keyPath.split('.');
list.reduce((acc, key, index) => {
if (index === list.length - 1) {
acc[key] = value;
return;
} else {
acc[key] = acc[key] || {};
return acc[key];
}
}, res);
});
return res;
}
function test(obj) {
const result = {};
for (const key of Object.keys(obj)) {
const list = key.split(".");
let temp = result;
while (list.length) {
let keyvalue = list.shift();
temp[keyvalue] = list.length ? temp[keyvalue] || {} : obj[key];
temp = temp[keyvalue];
}
}
return result;
}
var data = {
'a.b.c': 'ccc',
'a.b.d': 'ddd',
'a.e': 'eee'
}
function solution(data) {
var result = {}
Object.keys(data).forEach((key) => {
const arr = key.split('.');
arr.reduce((acc, cur, index) => {
acc[cur] = acc[cur] || {}
if (index === arr.length - 1) {
acc[cur] = data[key]
}
return acc[cur]
}, result)
})
return result
}
console.log('solution: ', solution(data));
function transfer(entry) {
const result = {};
Object.entries(entry).forEach(([string, value]) => {
const keys = string.split('.');
let temp = result;
keys.forEach((key, index) => {
if (index === keys.length - 1) {
temp[key] = value;
} else if (typeof temp[key] === 'undefined') {
temp[key] = {};
}
temp = temp[key];
});
});
return result;
}
var entry = {
'a.b.c.dd': 'abcdd',
'a.b.c.d.e': 'abcde',
'a.d.xx': 'adxx',
'a.e': 'ae'
}
function convert4(entry) {
const result = {};
for (let key of Object.keys(entry)) {
key.split('.').reduce((acc, cur, i, paths) => acc[cur] ??= (i === paths.length -1 ? entry[key] : {}), result)
}
return result;
}
console.log(convert4(entry))
function format(obj) {
const result = {};
for (let key in obj) {
const arr = key.split(".");
dfs(arr, result, obj[key]);
}
return result;
function dfs(array, target, value) {
if (!array.length) {
return;
}
const key = array[0];
if (array.length === 1) {
target[key] = value;
} else {
const copiedArray = [...array];
target[key] = target[key] || {};
copiedArray.shift();
dfs(copiedArray, target[key], value);
}
}
}
// output = {
// a: {
// b: {
// c: {
// dd: 'abcdd'
// }
// },
// d: {
// xx: 'adxx'
// },
// e: 'ae'
// }
// }
console.debug(
format({
"a.b.c.dd": "abcdd",
"a.d.xx": "adxx",
"a.e": "ae",
})
);