从Array创建未知深度的Object的通用解决方案 [英] Generic solution to create an Object of unknown deepth from an Array

查看:49
本文介绍了从Array创建未知深度的Object的通用解决方案的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要创建一个JSON对象,如下所示:

I need to create a JSON object as follows:

{
    "app_name": "foo",
    "meta": {
        "title": "foo",
        "lang": "bar"
    },
    "teaser": {
        "foo": {
            "headline": "foo",
            "subline": "bar"
        }
    }
}

对象树以下列表示形式提供:

The object tree is provided in the following representation:

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"
    }
];

现在,我找不到通用解决方案了。这里有一些适用于给定(简化)示例的代码:

Now, I can't find a generic solution at the moment. Here's some code that would work for the given (simplified) example:

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;
        }
    }
}

但这很难看不可靠的。我想替换这部分:

But this is as ugly as unreliable. I'd like to replace this part:

    if (keyDepth === 1) {
        finalObject[keyArray[0]] = translationVal;
    } else if (keyDepth === 2) {
       //...
    }

with

    if (keyDepth === 1) {
        finalObject[keyArray[0]] = translationVal;
    } else {
        //some generic solution, which works for any deepth
    }

任何想法?

推荐答案

如果属性不是,您可以使用默认对象采用迭代方法存在。

You could take an iterative approach by using a default object if a property does not exists.

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; }

这篇关于从Array创建未知深度的Object的通用解决方案的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆