anytree icon indicating copy to clipboard operation
anytree copied to clipboard

Add hierarchy wildcard `**` to Resolver.glob()

Open Odelya opened this issue 7 years ago • 4 comments

Version 2.1.1 - glob returns only the closest children:

d = Node("parent")
child_1 = Node("child_1", parent=d, value="5")
child_2 = Node("child_2", parent=d, value="5")
grandson_1 = Node("child_1", parent=child_1, value="5")
grandson_2 = Node("child_1", parent=child_1, value="5")
r = Resolver("value")
nodes = r.glob(d, "5")

Will return only child_1 and child_2

Odelya avatar Mar 28 '17 06:03 Odelya

This is the intended behaviour here. The glob() implementation lacks of a hierarchy wildcard like **. This might be implemented in a future release:

r.glob(d, "**/5")

Just use an iterator with a filter, which does the **/5:

nodes = list(PreOrderIter(d, lambda n: hasattr(n, "value") and n.value == "5"))

Or with wildcard matching:

from fnmatch import fnmatchcase
nodes = list(PreOrderIter(d, lambda n: hasattr(n, "value") and fnmatchcase(n.value, "*5")))

I would change this ticket into a feature request for hierarchy wildcard **.

HTH

c0fec0de avatar Mar 28 '17 07:03 c0fec0de

Yes, I used iterator instead. in that case - what's the difference between glob and iterator? Would wild card support any descendant without specifying the amount of ** ?

Odelya avatar Mar 28 '17 08:03 Odelya

The Resolver() eases the tree interaction on a higher level. The iterator gives you more flexibility.

** will match any descendant.

If you just want to have the first three level, you can invoke glob() multiple times and concatenate the result:

nodes = list(glob('5')) + list(glob('*/5')) + list (glob('*/*/5'))

Anyway. An iterator with a maxlevel is more elegant:

nodes = list(PreOrderIter(d, maxlevel=3, filter_=lambda n: hasattr(n, "value") and n.value == "5"))

c0fec0de avatar Mar 28 '17 08:03 c0fec0de

This would be very handy, indeed!

** will match any descendant.

I think, it should also allowed to be empty, i.e. match the root.

moi90 avatar Jun 30 '22 06:06 moi90