动态创建嵌套的JSON对象?

时间:2013-07-31 06:41:06

标签: javascript json object

我几乎就是这样,但似乎无法按计划实现此功能。

我有json' jsonData'它包含不同术语的公式

"jsonData":{
            "a" : "b + c",
            "b" : "d + e",
            "d" : "h + i",
            "c" : "f + g"
        }

我要做的是让一个函数传递一个参数' mainItem'(即' jsonData中的一个键'例如a in& #39; jsonData&#39)。在这个函数中,它将从json数据中获取公式(例如a是' mainitem'而b + c是公式)并检查公式的子组件的依赖关系,即它将检查{j}数据中bc是否具有任何依赖性。如果它具有任何依赖性,则它将作为子组件添加到父组件,例如,如果b在json数据中具有公式。 b将被添加为' mainitem'在父母的主要部分' mainitem' a。在代码的最后,这是我想要的。

{
mainitem : "a",
formula : "b+c",
childComponent: {
                 mainitem: "b",
                 formula : "d+e",
                 childcomponent: {
                                  mainitem: "d",
                                  formula : "h+i"
                                  }
                 },
                 {
                 mainitem: "c",
                 formula : "f+g"
                 },
}

问题在于我能够创建父对象。但我不知道如何为父组件创建子组件,如果子组件具有子子组件,它也将嵌入为子组件的子组件,依此类推。它就像父子层次结构系列

function getJson(mainItem) {
  var json = {};
  json['mainitem'] = mainItem;
  $.each(jsonData, function(key, value){
    if(mainitem == key){
      json['formula'] = value;
    }
  })
}

任何对此的见解都将受到高度赞赏。谢谢。

4 个答案:

答案 0 :(得分:2)

您需要/可以编写一个递归函数,将“公式”拆分为每个组合组件/项目,然后检查每个组件/项目的依赖关系。

以下是您的解决方案:http://jsfiddle.net/mqchen/4x7cD/

function getJson(item, data) {

    if(!data["jsonData"].hasOwnProperty(item)) return null;

    var out = {
        mainItem: item, 
        formula: data["jsonData"][item]
    };

    // Break up formula
    var components = out.formula.split(" ");

    for(var i = 0; i < components.length; i++) {
        var child = getJson(components[i], data); // Recursive call to get childComponents
        if(child !== null) {
            out["childComponent"] = out["childComponent"] == undefined ? [] : out["childComponent"];
            out["childComponent"].push(child);
        }
    }

    return out;
}

// Call it
getJson("a", data)

注意:它不考虑循环依赖关系,即如果你有a: "b + c", b: "d + a"

答案 1 :(得分:1)

这是一个依赖性问题。我已经可以提前告诉你,你需要找到一种处理循环依赖的方法(你不想在尝试生成输出时被抛入无限循环/递归)。我们来看看基本算法吧。我们需要什么东西?

  1. 我们需要一种方法来解析公式,使它们有意义。对于这个例子,我假设我们将获得a + b + c形式的输入,其中我只期望项目和+分隔每个项目。
  2. 我们需要一种方法来减少项目的依赖关系,以创建嵌套的childcomponent

    // assuming jsonData is available in this scope
    
    function getStructure (elem) {
        elem = $.trim(elem);
    
        // handling an element that doesn't exist in jsonData
        if (!jsonData[elem]) {
            return {
                'mainitem': elem,
                'formula': 'none' // or whatever you want to put
            };
        }
    
        var result = {},
            formula = jsonData[elem],
            children = formula.split('+'),
            i;
    
        result['mainitem'] = elem;
        result['formula'] = formula;
    
        // or however you want to store the child components
        result['childComponent'] = [];
    
        for (i = 0; i < children.length; i += 1) {
            result['childComponent'].push(getStructure(children[i]));
        }
    
        return result;
    }
    

答案 2 :(得分:1)

是的,这是一种构建语法树,就像经典的解析器/编译器问题一样。

我编写这个简单的递归函数的任何方法都能满足您的需求。虽然如果你的目标是构建某种解析器,那么你必须考虑遵循解析器/编译器构建原则,因为一旦函数开始增长,这将使事情易于管理和掌握。

    function getJson(mainitem,outjson)
    {
        formula = jsonData[mainitem]; 
        outjson.mainitem = mainitem;

        if (formula != null)
        {
            outjson.formula = formula;
            var firstItem = formula.toString().charAt(0);
            var secondItem = formula.charAt(formula.length - 1);                
            outjson.firstchild = {};
            outjson.secondchild = {};
            getJson(firstItem, outjson.firstchild);
            getJson(secondItem, outjson.secondchild);
        }
    }

你所要做的就是创建一个空对象并将其与问题中的操作数一起传递给getJson(),即mainitem:

    var outjson = {};
    getJson("a", outjson);

我使用JSON库将outjson对象转换为JSON文本。

此外,我已记录此outjson,以便您可以在嵌入式firebug lites'控制台窗口中进行检查。

JSFiddle找到它。

答案 3 :(得分:0)

已有批准的答案,但这是我的5美分。

as @ Mahesha999表示你需要像经典解析器/编译器一样构建“语法树”。 对于某些理论+示例,请查看videos

他们专注于antlr,但也包含很多关于解析器的理论。另外antlr有javascript插件可以使用。

我认为这比任何表达评估都好。