J'ai un tas d'objets dans une structure plate. Ces objets ont une propriété ID
et une ParentID
propriété afin de pouvoir être disposés en arbres. Ils ne sont pas dans un ordre particulier. Chaque ParentID
propriété ne correspond pas nécessairement à un ID
dans la structure. Il pourrait donc y avoir plusieurs arbres émergeant de ces objets.
Comment traiteriez-vous ces objets pour créer les arbres résultants?
Je ne suis pas si loin d'une solution mais je suis sûr que c'est loin d'être optimal ...
Je dois créer ces arbres pour ensuite insérer des données dans une base de données, dans le bon ordre.
Il n'y a pas de références circulaires. Un nœud est un nœud racine lorsque ParentID == null ou lorsque ParentID est introuvable dans les autres objets
Réponses:
Stockez les ID des objets dans une table de hachage mappant à l'objet spécifique. Énumérer tous les objets et trouver leur parent s'il existe et mettre à jour son pointeur parent en conséquence.
la source
Sur la base de la réponse de Mehrdad Afshari et du commentaire d'Andrew Hanlon pour une accélération, voici mon avis.
Différence importante par rapport à la tâche d'origine: un nœud racine a l'ID == parentID.
la source
Voici un algorithme JavaScript simple pour analyser une table plate en une arborescence parent / enfant qui s'exécute en N temps:
la source
console.log(JSON.stringify(root, null, 2));
pour imprimer la sortie.Solution Python
Par exemple:
Produit:
la source
def recurse(id, pages): for row in rows: if row['id'] == id: print(f'''{row['id']}:{row['parent_id']} {row['path']} {row['title']}''') recurse(row['id'], rows)
Version JS qui renvoie une racine ou un tableau de racines dont chacune aura une propriété de tableau Children contenant les enfants associés. Ne dépend pas d'une entrée ordonnée, compacte décemment et n'utilise pas de récursivité. Prendre plaisir!
la source
J'ai trouvé une version JavaScript géniale ici: http://oskarhane.com/create-a-nested-array-recursively-in-javascript/
Disons que vous avez un tableau comme celui-ci:
Et vous voulez que les objets soient imbriqués comme ceci:
Voici une fonction récursive qui le rend possible.
Usuage:
la source
Pour toute personne intéressée par une version C # de la solution d'Eugene, notez que node_list est accessible sous forme de carte, utilisez donc un dictionnaire à la place.
Gardez à l'esprit que cette solution ne fonctionne que si la table est triée par parent_id .
Le nœud est défini comme suit.
la source
new Node { parent_id = 7, id = 9 },
empêchenode_list.Add(item.id, item);
de se terminer car Key ne peut pas se répéter; c'est une faute de frappe; donc, au lieu de id = 9 , tapez id = 8J'ai écrit une solution générique en C # vaguement basée sur la réponse @Mehrdad Afshari:
la source
Voici la solution java de la réponse de Mehrdad Afshari.
la source
Aussi vague que la question me semble, je créerais probablement une carte de l'ID à l'objet réel. En pseudo-java (je n'ai pas vérifié si cela fonctionne / compile), cela pourrait être quelque chose comme:
Et pour rechercher chaque parent:
En réutilisant
getRealObject(ID)
et en effectuant une mappe d'un objet à une collection d'objets (ou leurs ID), vous obtenez également une mappe parent-> enfants.la source
Je peux le faire en 4 lignes de code et en temps O (n log n), en supposant que Dictionary est quelque chose comme un TreeMap.
EDIT : Ok, et maintenant j'ai lu que certains parentsID sont faux, alors oubliez ce qui précède et faites ceci:
la source
La plupart des réponses supposent que vous cherchez à faire cela en dehors de la base de données. Si vos arbres sont de nature relativement statique et que vous avez juste besoin de mapper les arbres dans la base de données, vous pouvez envisager d'utiliser des représentations d'ensemble imbriquées côté base de données. Consultez les livres de Joe Celko (ou ici pour un aperçu de Celko).
S'il est lié à Oracle dbs de toute façon, consultez leur CONNECT BY pour des approches SQL directes.
Dans les deux cas, vous pouvez ignorer complètement le mappage des arborescences avant de charger les données dans la base de données. Je pensais juste que je proposerais cela comme une alternative, cela peut être complètement inapproprié pour vos besoins spécifiques. L'ensemble de la partie "ordre correct" de la question initiale implique quelque peu que l'ordre soit "correct" dans la base de données pour une raison quelconque? Cela pourrait me pousser à manipuler les arbres là aussi.
la source
Ce n'est pas exactement la même chose que ce que le demandeur a recherché, mais j'ai eu du mal à comprendre les réponses formulées de manière ambiguë ici, et je pense toujours que cette réponse s'inscrit dans le titre.
Ma réponse est de mapper une structure plate sur une arborescence directement sur l'objet où tout ce que vous avez est un
ParentID
sur chaque objet.ParentID
estnull
ou0
s'il s'agit d'une racine. En face du demandeur, je suppose que toutParentID
le point de vue valide vers quelque chose d 'autre dans la liste:la source
voici une implémentation ruby:
Il cataloguera par nom d'attribut ou par le résultat d'un appel de méthode.
la source
La réponse acceptée me semble beaucoup trop complexe, j'ajoute donc une version Ruby et NodeJS de celle-ci
Supposons que la liste de nœuds plats ait la structure suivante:
Les fonctions qui transformeront la structure de liste plate ci-dessus en un arbre se présentent de la manière suivante
pour Ruby:
pour NodeJS:
la source
null
doit être pourundefined
null == undefined => true
dans NodeJSune manière élégante de le faire est de représenter les éléments de la liste sous forme de chaîne contenant une liste de parents séparés par des points, et enfin une valeur:
Lors de l'assemblage d'un arbre, vous vous retrouveriez avec quelque chose comme:
J'ai une bibliothèque de configuration qui implémente cette configuration de remplacement (arborescence) à partir d'arguments de ligne de commande (liste). L'algorithme pour ajouter un seul élément à la liste dans un arbre est ici .
la source
Êtes-vous bloqué en utilisant uniquement ces attributs? Sinon, il peut être intéressant de créer un tableau de nœuds enfants, dans lequel vous pouvez parcourir tous ces objets une fois pour créer de tels attributs. À partir de là, sélectionnez le nœud avec des enfants mais pas de parents et construisez de manière itérative votre arbre de haut en bas.
la source
version java
la source