我使用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"}]
parentlevel和treelevel是构成树关系的2个键。
新格式的app值是来自所有的app和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;
};
答案 0 :(得分:0)
这个想法是在最大深度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);
&#13;