2

我几乎可以做到这一点,但似乎无法按计划执行此功能。

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

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

我想要做的是让一个函数传递一个参数'mainItem'(即'jsonData'中的键之一,例如a'jsonData')。在此函数中,它将从 json 数据中获取公式(例如,a 是“mainitem”并且b + c是公式)并检查公式的子组件的依赖关系,即它将检查 json 中是否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

4 回答 4

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".

于 2013-07-31T07:03:57.100 回答
1

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

  1. 我们需要一种方法来解析公式,使它们有意义。对于这个例子,我假设我们会得到一个形式为 的输入,a + b + c在这里我只期望项目并+分隔每个项目。
  2. 我们需要一种方法来递归下一个项目的依赖项以创建嵌套childcomponent的 s。

    // 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;
    }
    
于 2013-07-31T07:03:36.730 回答
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找到它。

于 2013-07-31T08:58:07.997 回答
0

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

正如@Mahesha999 所说,您需要构建“经典解析器/编译器中的语法树”。有关一些理论 + 示例,请查看这些视频

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

我认为它比任何表达式评估都要好。

于 2013-07-31T12:43:20.783 回答