我有一个对象数组。
{
c1 : ["a1", "c2"],
c2 : ["b1"],
c3: ["d1"],
b1: ["e"]
d1: ["k"]
}
我需要按层次结构排列对象。像这样
{
c1: [{a1: null}, {
c2: [{
b1: "e"
}]
}],
c3: [{ d1: "k" }]
}
请注意,我们可以省略最后一个(最深)键:值对 中的数组。这是我迄今为止尝试过的。
for (v in hash){
hash[v].forEach(function(ar){
if(hash[ar]){
if (new_hash[v] == undefined){
new_hash[v] = []
}
new_hash[v].push({[ar] : hash[ar]})
}
})
}
我认为这个问题需要动态编程(保存状态的递归),但我这样做不好。请帮忙。
答案 0 :(得分:2)
您可以获取另一个哈希表并在其中存储所有节点之间的关系,并针对没有父节点的仅结果节点删除该关系。
为了克服没有子节点的问题,我添加了一个空数组,因为原始的所需结构要么具有null
要么根本没有子节点(如该节点)
{ b1: "e" }
与空标记一样应为
{ b1: [{ e: null }] }
此解决方案的特征是一个空数组,可以将其替换为任何其他值。
{ b1: [{ e: [] }] }
var hash = { c1: ["a1", "c2"], c2: ["b1"], c3: ["d1"], b1: ["e"], d1: ["k"] },
keys = Object.keys(hash),
parents = new Set(keys),
temp = {},
tree ;
keys.forEach(k => hash[k].forEach(t => {
parents.delete(t);
temp[k] = temp[k] || [];
temp[t] = temp[t] || [];
if (!temp[k].some(o => t in o)) temp[k].push({ [t]: temp[t] });
}));
tree = Object.assign({}, ...Array.from(parents, k => ({ [k]: temp[k] })));
console.log(tree);
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 1 :(得分:1)
您可以在没有递归关系的情况下遍历该父母-子女列表。
我省去了将代码实际转换为您描述的格式的代码,因为对我来说这是很早的事情,但是转换应该非常简单。
const data = {
c1: ["a1", "c2"],
c2: ["b1"],
c3: ["d1"],
b1: ["e"],
d1: ["k"],
};
// Generate a hash of nodes, mapping them to their children and parents.
const nodes = {};
Object.entries(data).forEach(([parentId, childIds]) => {
const parent = (nodes[parentId] = nodes[parentId] || {
id: parentId,
children: [],
});
childIds.forEach(childId => {
const child = (nodes[childId] = nodes[childId] || {
id: childId,
children: [],
});
parent.children.push(child);
child.parent = parent;
});
});
// Filter in only the nodes with no parents
const rootNodes = {};
Object.values(nodes).forEach(node => {
// TODO: transform the {id, children, parent} nodes to whichever format you require
if (!node.parent) rootNodes[node.id] = node;
});
rootNodes
看起来像
{
c1: {
id: 'c1',
children: [
{ id: 'a1', children: [], parent: ... },
{
id: 'c2',
children: [
{
id: 'b1',
children: [ { id: 'e', children: [], parent: ... } ],
parent: ...
}
],
parent: ...
}
]
},
c3: {
id: 'c3',
children: [
{
id: 'd1',
children: [ { id: 'k', children: [], parent: ... } ],
parent: ...
}
]
}
}
答案 2 :(得分:1)
您可以使用reduce
方法创建一个函数来循环Object.keys并构建新的对象结构,还可以使用另一个函数来检查当前键是否已存在于对象中并返回它。
const data = {
c1: ["a1", "c2"],
c2: ["b1"],
c3: ["d1"],
b1: ["e"],
d1: ["k"]
}
function find(obj, key) {
let result = null
for (let i in obj) {
if (obj[i] === key || i === key) {
result = obj
}
if (!result && typeof obj[i] == 'object') {
result = find(obj[i], key)
}
}
return result
}
function nest(data) {
return Object.keys(data).reduce((r, e) => {
const match = find(r, e);
if (match) {
if (!match[e]) match[e] = []
match[e].push({
[data[e]]: null
})
} else {
data[e].forEach(el => {
if (!r[e]) r[e] = [];
r[e].push({
[el]: null
})
})
}
return r;
}, {})
}
const result = nest(data);
console.log(result)