[英]Reformatting hierarchical JSON data
我有以下使用PHP从PostgreSQL数据库中检索到的分层JSON数据:
[{"treelevel":"1","app":"Front","lrflag":null,"ic":null,"price":null,"parentlevel":"0","seq":"27", "indexlistid":439755},
{"treelevel":"2","app":"V-Series","lrflag":null,"ic":null,"price":null,"parentlevel":"1","seq":"28", "indexlistid":439755},
{"treelevel":"3","app":"opt J56","lrflag":null,"ic":null,"price":null,"parentlevel":"2","seq":"29", "indexlistid":439755},
{"treelevel":"4","app":"R.","lrflag":"R","ic":"536-01132AR","price":"693.00","parentlevel":"3","seq":"30", "indexlistid":439755},
{"treelevel":"4","app":"L.","lrflag":"L","ic":"536-01133AL","price":"693.00","parentlevel":"3","seq":"31", "indexlistid":439755},
{"treelevel":"3","app":"opt J63","lrflag":null,"ic":null,"price":null,"parentlevel":"2","seq":"32", "indexlistid":439755},
{"treelevel":"4","app":"R.","lrflag":"R","ic":"536-01130R","price":null,"parentlevel":"3","seq":"33", "indexlistid":439755},
{"treelevel":"4","app":"L.","lrflag":"L","ic":"536-01131L","price":null,"parentlevel":"3","seq":"34", "indexlistid":439755}]
我需要一些重新格式化数据的方法:
[{"app": "Front-V-Series-opt J56-R. R", "price": "$693", "ic": "536-01132AR"},
{"app": "Front-V-Series-opt J56-L. L", "price": "$693", "ic": "536-01132AL"},
{"app": "Front-V-Series-opt J63-R. R", "price": null, "ic": "536-01130R"},
{"app": "Front-V-Series-opt J63-L. L", "price": null, "ic": "536-01131L"}]
父级和树级是构成树关系的两个键。
新格式的应用程序值是一个树级别中所有节点的应用程序和lrflag值加上该级别中最深叶节点的价格和ic的串联。 这是可视化为树的数据:
[
{
"app": "Front",
"children": [
{
"app": "V-Series",
"children": [
{
"app": "opt J56",
"children": [
{
"app": "R. ,
"lrflag": "R",
"ic": "536-01132AR",
"price": "$693"
},
{
"app": "L. ,
"lrflag": "L",
"ic": "536-01132AL",
"price": "$693"
}
]
},
{
"app": "opt J63",
"children": [
{
"app": "R. ,
"lrflag": "R",
"ic": "536-01130R"
},
{
"app": "L. ,
"lrflag": "L",
"ic": "536-01131L"
}
]
}
]
}
]
}
]
我尝试了几种不同的方法来做到这一点,但被困住了。 这是我尝试修改并使用的一些功能,以免碰运气。 我什至无法从这些树中正确构建树。
function buildTree(list) {
var map = {}, node, roots = [], i;
for (i = 0; i < list.length; i += 1) {
map[list[i].treelevel] = i; // initialize the map
list[i].children = []; // initialize the children
}
for (i = 0; i < list.length; i += 1) {
node = list[i];
if (node.parentlevel !== "0") {
// if you have dangling branches check that map[node.parentId] exists
list[map[node.parentlevel]].children.push(node);
} else {
roots.push(node);
}
}
return roots;
}
function listToTree(data, options) {
options = options || {};
var ID_KEY = options.idKey || 'treelevel';
var PARENT_KEY = options.parentKey || 'parentlevel';
var CHILDREN_KEY = options.childrenKey || 'children';
var tree = [],
childrenOf = {};
var item, id, parentId;
for (var i = 0, length = data.length; i < length; i++) {
item = data[i];
id = item[ID_KEY];
parentId = item[PARENT_KEY] || 0;
// every item may have children
childrenOf[id] = childrenOf[id] || [];
// init its children
item[CHILDREN_KEY] = childrenOf[id];
if (parentId != 0) {
// init its parent's children object
childrenOf[parentId] = childrenOf[parentId] || [];
// push it into its parent's children object
childrenOf[parentId].push(item);
} else {
tree.push(item);
}
};
return tree;
}
unflattenToObject = function(array, parent) {
var tree = {};
parent = typeof parent !== 'undefined' ? parent : {id: 0};
var childrenArray = array.filter(function(child) {
return child.treelevel == parent.parentlevel;
});
if (childrenArray.length > 0) {
var childrenObject = {};
// Transform children into a hash/object keyed on token
childrenArray.forEach(function(child) {
childrenObject[child.treelevel] = child;
});
if (parent.treelevel == 0) {
tree = childrenObject;
} else {
parent['children'] = childrenObject;
}
childrenArray.forEach(function(child) {
unflattenToObject(array, child);
})
}
return tree;
};
这个想法是在最大深度treelevel : 4
获取第一个元素的索引treelevel : 4
然后从那里开始并向后循环,确保您没有两次遍历父级,并在到达顶部时连接您需要的内容级别,则删除该元素
将其包装在函数中,并递归调用它,直到没有treelevel : 4
还剩treelevel : 4
var data = [{ "treelevel": "1", "app": "Front", "lrflag": null, "ic": null, "price": null, "parentlevel": "0", "seq": "27", "indexlistid": 439755 }, { "treelevel": "2", "app": "V-Series", "lrflag": null, "ic": null, "price": null, "parentlevel": "1", "seq": "28", "indexlistid": 439755 }, { "treelevel": "3", "app": "opt J56", "lrflag": null, "ic": null, "price": null, "parentlevel": "2", "seq": "29", "indexlistid": 439755 }, { "treelevel": "4", "app": "R.", "lrflag": "R", "ic": "536-01132AR", "price": "693.00", "parentlevel": "3", "seq": "30", "indexlistid": 439755 }, { "treelevel": "4", "app": "L.", "lrflag": "L", "ic": "536-01133AL", "price": "693.00", "parentlevel": "3", "seq": "31", "indexlistid": 439755 }, { "treelevel": "3", "app": "opt J63", "lrflag": null, "ic": null, "price": null, "parentlevel": "2", "seq": "32", "indexlistid": 439755 }, { "treelevel": "4", "app": "R.", "lrflag": "R", "ic": "536-01130R", "price": null, "parentlevel": "3", "seq": "33", "indexlistid": 439755 }, { "treelevel": "4", "app": "L.", "lrflag": "L", "ic": "536-01131L", "price": null, "parentlevel": "3", "seq": "34", "indexlistid": 439755 } ]; // first go look for the max depth in the tree, if it's always four, skip this part and put var max = 4 var max = 0; data.forEach(function(elem) { if (elem.treelevel >= max) max = elem.treelevel; }); // implement a function to get the index of the first matched element with treelevel = max depth function getIndex() { return data.indexOf(data.find((elem) => { return elem.treelevel == max; })); } var myTree = []; function formObject(ndx) { var myObj = {}; myObj.app = []; var nextTreeLevel = 3; // start looping from the index of the element in max depth backwards for (var i = ndx; i >= 0; i--) { // if the next element ( backwards ) is a parent , this is to avoid going through parent's siblings if (nextTreeLevel == data[i].parentlevel) { if (data[i].ic != null) myObj.ic = data[i].ic; if (data[i].price != null) myObj.price = data[i].price; if (data[i].lrflag != null) myObj.app.push(data[i].lrflag); myObj.app.push(data[i].app); nextTreeLevel = data[i].parentlevel - 1; // prent's level } } data.splice(ndx, 1); // remove the lement once you're done with it // glue the "app" together, would be better to use array.join but it's not the same join everywhere myObj.app = myObj.app[4] + '-' + myObj.app[3] + '-' + myObj.app[2] + '-' + myObj.app[1] + ' ' + myObj.app[0]; // just to fill the price with null if there is none if (myObj.price == undefined) myObj.price = null; // push the object to the result's array myTree.push(myObj); // get the index of the next element in max depth ( 4 ) var nextIndex = getIndex(); // if there's still another element in the max depth, recall the same function with it's index if (nextIndex > -1) formObject(nextIndex) } formObject(getIndex()) console.log(myTree);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.