J'ai un tableau d'objets.
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]}) } }) }
J'ai besoin que l'objet soit organisé dans une hiérarchie. comme ceci,
{ c1: [{a1: null}, { c2: [{ b1: "e" }] }], c3: [{ d1: "k" }] }
Notez que nous pouvons omettre le tableau dans dernière paire clé (la plus profonde): valeur . C'est ce que j'ai essayé jusqu'à présent.
{ c1 : ["a1", "c2"], c2 : ["b1"], c3: ["d1"], b1: ["e"] d1: ["k"] }
Je pense que ce problème nécessite une programmation dynamique (récursion avec sauvegarde de l'état) dans laquelle je ne suis pas bon. Veuillez aider.
3 Réponses :
Vous pouvez parcourir cette liste parents-enfants sans récursivité pour obtenir l'arborescence.
J'ai omis le code pour transformer les nœuds dans le format que vous décrivez car il est assez tôt le matin pour moi, mais le la transformation devrait être assez simple.
{ 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: ... } ] } }
rootNodes
ressemblera à
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; });
Vous pourriez prendre une autre table de hachage et y stocker la relation entre tous les nœuds et en retirer pour le résultat uniquement les nœuds qui n'ont pas de parents.
Pour surmonter le problème des nœuds sans enfants, j'ai ajouté un tableau vide, parce que la structure recherchée d'origine a soit null
ou aucun enfant du tout, comme ce nœud
.as-console-wrapper { max-height: 100% !important; top: 0; }
où, comme avec un marqueur nul, il devrait être p>
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);
Cette solution comporte un tableau vide, qui peut être remplacé par n'importe quelle autre valeur.
{ b1: [{ e: [] }] }
{ b1: [{ e: null }] }
{ b1: "e" }
Vous pouvez créer une fonction avec la méthode reduction
pour boucler Object.keys et créer une nouvelle structure d'objet et une autre fonction pour vérifier si la clé actuelle est déjà dans l'objet et la renvoyer.
p>
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)
Je pense que vous avez un objet dont les propriétés sont des tableaux, et non l'inverse. ;-) D'où vient new_hash ?