Reputation: 3829
I am almost there with this but cannot seem to get this functionality going as planned.
I have json 'jsonData' it contains formula of different terms
"jsonData":{
"a" : "b + c",
"b" : "d + e",
"d" : "h + i",
"c" : "f + g"
}
What I am trying to do is to have a function pass one arguments 'mainItem'(ie. one of the key in 'jsonData' for example a
in 'jsonData'). Within this function it will get the formula from the json data(for example a is the 'mainitem' and b + c
is the formula) and check the dependency of child component of the formula i.e it will check whether b
and c
have any dependency down the line in json data. If it has any dependency it will be added as a child component to the parent for example if b
have a formula in json data. b
will be added as the 'mainitem' in the child component of the parent 'mainitem' a
. At the end of the code, this is what I would like to get.
{
mainitem : "a",
formula : "b+c",
childComponent: {
mainitem: "b",
formula : "d+e",
childcomponent: {
mainitem: "d",
formula : "h+i"
}
},
{
mainitem: "c",
formula : "f+g"
},
}
The issue is that I am able to create the parent object. But I have no idea how to create the child component for the parent and If the child component have sub child it will also embedded as the child of the child component and so on. It is like a parent child hierarchy series
function getJson(mainItem) {
var json = {};
json['mainitem'] = mainItem;
$.each(jsonData, function(key, value){
if(mainitem == key){
json['formula'] = value;
}
})
}
Any insight into this would highly be appreciated. Thank you.
Upvotes: 2
Views: 7890
Reputation: 4193
You need/could to write a recursive function that splits up the "formula" into each composing component/item and then check each component/item for their dependencies.
Here is a solution for you: 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)
Note: It does not consider circular dependencies, i.e. if you have a: "b + c", b: "d + a"
.
Upvotes: 2
Reputation: 2262
There is approved answer already but here are my 5 cents.
as @Mahesha999 said you need to build "Syntax Tree as in classic parser/compiler". For some theory + examples look at those videos
They are focused on antlr but also contains a lot theory about parsers. Also antlr have javascript plugin that can be used.
I think it's better than any expression evaluation.
Upvotes: 0
Reputation: 24931
Yeah this is some sort of building Syntax Tree as in classic parser/compiler problem.
Any ways I have written this simple recursive function that does what you want. Though if your goal is to build some sort of parser then you must think of following parser / compiler building principles since that will keep things manageable and graspable once functions start growing.
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);
}
}
What all you have to do is to create an empty object and pass it to getJson()
along with the operand in problem i.e. mainitem:
var outjson = {};
getJson("a", outjson);
I have used JSON
library to convert outjson
object to JSON text.
Also I have logged this outjson
so that you can examine it in the embedded firebug lites' Console window.
Find it at JSFiddle.
Upvotes: 1
Reputation: 6342
This is a dependency problem. I can already tell you ahead of time that you will need to figure out a way to handle circular dependencies (you don't want to get thrown into an infinite loop/recursion when trying to generate the output). Let's go through the basic algorithm. What are some things we need?
a + b + c
, where I only expect the item and +
to delimit each item.We need a way to recurse down an item's dependencies to create nested 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;
}
Upvotes: 1