New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enhancement/question: Find lowest common ancestor of two or more nodes? #44
Comments
I will add an commonanchestors function the next days. |
Here is a possible implementation... def commonAncestor(n, *rest):
'''
:param n: 1st node to check
:param rest: all remaining nodes check
:type node: Node
:type rest: list[Node]
:return: deepest common Node
>>> from anytree import Node, RenderTree
>>> udo = Node("Udo")
>>> marc = Node("Marc", parent=udo)
>>> lian = Node("Lian", parent=marc)
>>> dan = Node("Dan", parent=udo)
>>> jet = Node("Jet", parent=dan)
>>> jan = Node("Jan", parent=dan)
>>> joe = Node("Joe", parent=dan)
>>> mary = Node("Mary")
>>> urs = Node("Urs", parent=mary)
>>> chris = Node("Chris", parent=mary)
>>> marta = Node("Marta", parent=mary)
>>> udo.parent = mary
>>> print(RenderTree(mary))
Node('/Mary')
├── Node('/Mary/Urs')
├── Node('/Mary/Chris')
├── Node('/Mary/Marta')
└── Node('/Mary/Udo')
├── Node('/Mary/Udo/Marc')
│ └── Node('/Mary/Udo/Marc/Lian')
└── Node('/Mary/Udo/Dan')
├── Node('/Mary/Udo/Dan/Jet')
├── Node('/Mary/Udo/Dan/Jan')
└── Node('/Mary/Udo/Dan/Joe')
>>> print(commonAncestors(marta))
Node('/Mary/Marta')
>>> print(commonAncestors(lian, joe))
Node('/Mary/Udo')
>>> print(commonAncestors(jet, jan))
Node('/Mary/Udo/Dan')
>>> print(commonAncestors(joe, marc, urs))
Node('/Mary')
'''
if len(rest):
common = list(reduce(lambda x,y: x & y, [set(nn.ancestors) for nn in rest], set(n.ancestors)))
if not common:
raise RuntimeError('No common nodes')
common.sort(key=lambda x: x.depth)
deepest = common[-1]
return deepest
return n |
Thanks for the request and the contribution. The example I just added a function in a new utilities module. |
Could you please add the util package to the config['packages'] in the setup.py |
Hi, in anytree v 2.8.0, regarding the lowest common ancestor, using the example above: commonancestors(marc, lian)
(Node('/Mary'), Node('/Mary/Udo')) Since Lian is a direct descendant of Marc, shouldn't it return
Thank you! |
Is there any way to extract lowest common ancestor of nodes without iterating over the ancestor names and finding the common ancestor "manually"? For two nodes it's not too bad, but for more nodes I'm not actually sure how one would accomplish this.
The text was updated successfully, but these errors were encountered: