我需要创建一个JSON对象,如下所示:
{
"app_name": "foo",
"meta": {
"title": "foo",
"lang": "bar"
},
"teaser": {
"foo": {
"headline": "foo",
"subline": "bar"
}
}
}
对象树按以下表示形式提供:
var translations = [
{
"key": "app_name",
"val": "foo"
},
{
"key": "meta.title",
"val": "foo"
},
{
"key": "meta.lang",
"val": "bar"
},
{
"key": "teaser.foo.headline",
"val": "foo"
},
{
"key": "teaser.foo.subline",
"val": "bar"
}
];
现在,我无法找到通用的解决方案。这里有一些适用于给定(简化)示例的代码:
var finalObject = {};
for (var i in translations) {
var translation = translations[i],
translationKey = translation["key"],
translationVal = translation["val"];
var keyArray = translationKey.split("."),
keyDepth = keyArray.length;
if (keyDepth === 1) {
finalObject[keyArray[0]] = translationVal;
} else if (keyDepth === 2) {
if (typeof finalObject[keyArray[0]] === 'object') {
finalObject[keyArray[0]][keyArray[1]] = translationVal;
} else {
var item = {};
item[keyArray[1]] = translationVal;
finalObject[keyArray[0]] = item;
}
} else if (keyDepth === 3) {
if (finalObject[keyArray[0]] && finalObject[keyArray[0]][keyArray[1]] && typeof finalObject[keyArray[0]][keyArray[1]] === 'object') {
finalObject[keyArray[0]][keyArray[1]][keyArray[2]] = translationVal;
} else {
var item = {};
item[keyArray[2]] = translationVal;
if (!finalObject[keyArray[0]] || typeof finalObject[keyArray[0]] !== 'object') {
finalObject[keyArray[0]] = {};
}
finalObject[keyArray[0]][keyArray[1]] = item;
}
}
}
但这是不可靠的丑陋。我想替换这部分:
if (keyDepth === 1) {
finalObject[keyArray[0]] = translationVal;
} else if (keyDepth === 2) {
//...
}
与
if (keyDepth === 1) {
finalObject[keyArray[0]] = translationVal;
} else {
//some generic solution, which works for any deepth
}
有什么想法吗?
答案 0 :(得分:4)
如果属性不存在,您可以使用默认对象采用迭代方法。
function setValue(object, key, value) {
var path = key.split('.'),
last = path.pop();
path.reduce(function (o, k) {
return o[k] = o[k] || {};
}, object)[last] = value;
}
var translations = [{ key: "app_name", val: "foo" }, { key: "meta.title", val: "foo" }, { key: "meta.lang", val: "bar" }, { key: "teaser.foo.headline", val: "foo" }, { key: "teaser.foo.subline", val: "bar" }],
object = {};
translations.forEach(function (o) {
setValue(object, o.key, o.val);
});
console.log(object);
.as-console-wrapper { max-height: 100% !important; top: 0; }