我想将一个对象(输入)变成另一个(输出)。
例如,我得到了这个输入对象:
var input = {
'person1.name': 'John',
'person1.address.street': 'main street',
'person1.address.zipcode': 12345,
'person2.name': 'Smith',
'person2.address.street': 'major street',
'person2.address.zipcode': 12345
}
var output = {
person1: {
name: 'John',
address: {
street: 'Main Street',
zipcode: 12345
}
},
person2: {
name: 'Smith',
address: {
street: 'Major Street',
zipcode: 12345
}
}
}
我正在尝试做类似的事情,但未能完成:
const input= getInputValue();
const output = {};
for (let prop in input) {
let arr = prop.split('.');
arr.forEach(el => {
output[el] = output
})
}
答案 0 :(得分:2)
如果使用lodash,这非常简单。
参考:lodash _.set
函数
var input = {
'person1.name': 'John',
'person1.address.street': 'main street',
'person1.address.zipcode': 12345,
'person2.name': 'Smith',
'person2.address.street': 'major street',
'person2.address.zipcode': 12345
}
var output = {};
for (let prop in input) {
_.set(output, prop, input[prop]);
}
console.log(output);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
答案 1 :(得分:1)
您可以使用函数将路径拆分为值并为其生成新对象。
function setValue(object, path, value) {
var last = path.pop();
path.reduce((o, k) => o[k] = o[k] || {}, object)[last] = value;
return object;
}
var input = { 'person1.name': 'John', 'person1.address.street': 'main street', 'person1.address.zipcode': 12345, 'person2.name': 'Smith', 'person2.address.street': 'major street', 'person2.address.zipcode': 12345 },
output = {};
Object
.entries(input)
.forEach(([k, v]) => setValue(output, k.split('.'), v));
console.log(output);
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 2 :(得分:0)
这是基于您提供的forEach循环的另一种解决方案。
它使用parent
对将存储属性的对象的引用:
el
是数组中的最后一个,它将向父对象添加属性parent
引用设置为在树中创建的新对象。
var input = {
"person1.name": 'John',
"person1.address.street": 'main street',
"person1.address.zipcode": 12345,
"person2.name": 'Smith',
"person2.address.street": 'major street',
"person2.address.zipcode": 12345
}
const output = {};
for (let prop in input) {
let arr = prop.split('.');
let parent = output;
arr.forEach((el, index) => {
if (index === arr.length -1) {
// el is a leaf, time to add the value of the property in the parent
parent[el] = input[prop];
} else {
// el is not a leaf, create a node in the tree if it doesn't already exist
parent[el] = parent[el] || {};
}
// moving down the tree
parent = parent[el];
})
}
console.log(output);
答案 3 :(得分:0)
此示例无需更改原始对象即可完成您需要的操作
您可以使用递归并遍历keys数组,直到到达结尾为止:
https://jsfiddle.net/5ykbLpav/68/
var input = {
'person1.name': 'John',
'person1.address.street': 'main street',
'person1.address.zipcode': 12345,
'person2.name': 'Smith',
'person2.address.street': 'major street',
'person2.address.zipcode': 12346
}
function buildTree(obj, keys, val) {
let key = keys[0]
if (keys.length === 1) {
obj[key] = val
return obj
} else {
let nKeys = keys.slice().splice(1, keys.length)
// or if you are okay with mutation you could just do --> keys.shift()
let node = {};
if (obj[key]) {
node = obj[key]
}
obj[key] = buildTree(node, nKeys, val)
return obj
}
}
function cleanObject(obj) {
return Object.keys(obj).reduce((acc, curr) => {
let keys = curr.split('.')
return buildTree(acc, keys, obj[curr])
}, {})
}
let cleanObj = cleanObject(input)
console.log(cleanObj)