Reputation: 3457
I have a JSON as shown below
{
"name": "Soft Drinks",
"T2": [
{
"name": "Bottled",
"T3": [
{
"name": "Apple",
"leaf": [
{
"name": "Apple 500 ML"
},
{
"name": "Apple 1 Ltr"
}
]
}
]
},
{
"name": "Fountain",
"T3": [
{
"name": "Apple",
"leaf": [
{
"name": "Apple Regular, 500 ML"
}
]
}
]
},
{
"name": "Tin",
"T3": [
{
"name": "Apple",
"leaf": [
{
"name": "Apple Regular, 300 ML"
}
]
}
]
}
]
}
I will get a Input String as Path means this way as an array
1st case :
Input : Soft Drinks,Bottled
Output : ["Apple"]
2nd case :
Input : Soft Drinks,Fountain,Apple
Output
[
"leaf",
[
{
"name": "Apple Regular, 500 ML"
}
]
]
Could anybody please help me how to resolve this? I am forming this input array when navigated through the Jquery Accordian, so depending on the click, I need to show the respective data.
For your reference the screen looks this way
Upvotes: 0
Views: 80
Reputation: 7438
Some changes: every node has keys name and leaf,
var drinks = [
{
"name": "Soft Drinks",
"leaf": [
{
"name": "Bottled",
"leaf": [
{
"name": "Apple",
"leaf": [
{
"name": "Apple 500 ML"
},
{
"name": "Apple 1 Ltr"
}
]
}
]
},
{
"name": "Fountain",
"leaf": [
{
"name": "Apple",
"leaf": [
{
"name": "Apple Regular, 500 ML"
}
]
}
]
},
{
"name": "Tin",
"leaf": [
{
"name": "Apple",
"leaf": [
{
"name": "Apple Regular, 300 ML"
}
]
}
]
}
]
}
];
var drinkParser = (function () {
function DrinksCollection(nodes) {
extend(this, nodes);
this.length = nodes.length;
this.parent = null;
}
/*
* Method extend from Underscore.js 1.6.0
* http://underscorejs.org
* (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
* Underscore may be freely distributed under the MIT license.
*/
function extend(obj) {
Array.prototype.slice.call(arguments, 1).forEach(function (source) {
if (source) {
for (var prop in source) {
obj[prop] = source[prop];
}
}
});
return obj;
}
function nodeMatcher(node, selectorExpr) {
var type = typeof selectorExpr;
if (type === "string") {
return node.name === selectorExpr;
} else if (type === "function") {
return !!selectorExpr(node);
} else {
throw new TypeError("Cannot filter node with selector " + selectorExpr);
}
}
DrinksCollection.prototype = {
toArray: function () {
return Array.prototype.slice.call(this);
},
find: function (selectorExpr) {
var foundNodes = [];
this.walk(function (node) {
if (nodeMatcher(node, selectorExpr)) {
foundNodes.push(node);
}
});
return this.pushStack(foundNodes);
},
each: function (callback) {
this.toArray().forEach(callback);
return this;
},
map: function (callback) {
return this.toArray().map(callback);
},
walk: function (callback) {
function walk(node, index) {
callback.call(node, node, index);
(node.leaf || []).forEach(walk);
}
this.each(walk);
return this;
},
pushStack: function (nodes) {
var newInstance = new DrinksCollection(nodes);
newInstance.parent = this;
return newInstance;
},
children: function () {
var allChildren = [];
this.each(function (node) {
allChildren = allChildren.concat(node.leaf);
});
return this.pushStack(allChildren);
},
props: function (propName) {
return this.map(function (node) {
return node[propName];
});
},
names: function () {
return this.props("name");
}
};
return function (nodes) {
return new DrinksCollection(nodes);
}
}());
(function parseDrinks() {
console.log(drinkParser(drinks).find('Soft Drinks').find('Bottled').children().names()); // [ 'Apple' ]
console.log(drinkParser(drinks).find('Soft Drinks').find('Bottled').find('Apple').children().map(function (drink) {
return drink;
})); // [ { name: 'Apple 500 ML' }, { name: 'Apple 1 Ltr' } ]
}());
Upvotes: 1