phml.utils.locate.index
1# pylint: disable=missing-module-docstring 2from typing import Callable, Optional 3 4from phml.nodes import AST, Element, Root 5from phml.utils.validate.test import Test 6 7 8class Index: 9 """Uses the given key or key generator and creates a mutable dict of key value pairs 10 that can be easily indexed. 11 12 Nodes that don't match the condition or don't have a valid key are not indexed. 13 """ 14 15 indexed_tree: dict[str, list[Element]] 16 """The indexed collection of elements""" 17 18 def __init__( 19 self, key: str | Callable, start: AST | Root | Element, condition: Optional[Test] = None 20 ): 21 """ 22 Args: 23 `key` (str | Callable): Str represents the property to use as an index. Callable 24 represents a function to call on each element to generate a key. The returned key 25 must be able to be converted to a string. If none then element is skipped. 26 `start` (AST | Root | Element): The root or node to start at while indexing 27 `test` (Test): The test to apply to each node. Only valid/passing nodes 28 will be indexed 29 """ 30 from phml.utils import test, walk # pylint: disable=import-outside-toplevel 31 32 self.indexed_tree = {} 33 self.key = key 34 35 for node in walk(start): 36 if isinstance(node, Element): 37 if condition is not None: 38 if test(node, condition): 39 self.add(node) 40 else: 41 self.add(node) 42 43 def add(self, node: Element): 44 """Adds element to indexed collection if not already there.""" 45 46 key = node.properties[self.key] if isinstance(self.key, str) else self.key(node) 47 if key not in self.indexed_tree: 48 self.indexed_tree[key] = [node] 49 50 if node not in self.indexed_tree[key]: 51 self.indexed_tree[key].append(node) 52 53 def remove(self, node: Element): 54 """Removes element from indexed collection if there.""" 55 56 key = node.properties[self.key] if isinstance(self.key, str) else self.key(node) 57 if key in self.indexed_tree and node in self.indexed_tree[key]: 58 self.indexed_tree[key].remove(node) 59 60 def get(self, _key: str) -> Optional[list[Element]]: 61 """Get a specific index from the indexed tree.""" 62 return self.indexed_tree.get(_key) 63 64 def map(self, modifier: Callable) -> list: 65 """Applies the passed modifier to each index. 66 67 Returns: 68 list of results generated by the modifier applied 69 to each index. 70 """ 71 result = [] 72 for value in self.indexed_tree.values(): 73 result.extend([modifier(v) for v in value]) 74 return result
class
Index:
9class Index: 10 """Uses the given key or key generator and creates a mutable dict of key value pairs 11 that can be easily indexed. 12 13 Nodes that don't match the condition or don't have a valid key are not indexed. 14 """ 15 16 indexed_tree: dict[str, list[Element]] 17 """The indexed collection of elements""" 18 19 def __init__( 20 self, key: str | Callable, start: AST | Root | Element, condition: Optional[Test] = None 21 ): 22 """ 23 Args: 24 `key` (str | Callable): Str represents the property to use as an index. Callable 25 represents a function to call on each element to generate a key. The returned key 26 must be able to be converted to a string. If none then element is skipped. 27 `start` (AST | Root | Element): The root or node to start at while indexing 28 `test` (Test): The test to apply to each node. Only valid/passing nodes 29 will be indexed 30 """ 31 from phml.utils import test, walk # pylint: disable=import-outside-toplevel 32 33 self.indexed_tree = {} 34 self.key = key 35 36 for node in walk(start): 37 if isinstance(node, Element): 38 if condition is not None: 39 if test(node, condition): 40 self.add(node) 41 else: 42 self.add(node) 43 44 def add(self, node: Element): 45 """Adds element to indexed collection if not already there.""" 46 47 key = node.properties[self.key] if isinstance(self.key, str) else self.key(node) 48 if key not in self.indexed_tree: 49 self.indexed_tree[key] = [node] 50 51 if node not in self.indexed_tree[key]: 52 self.indexed_tree[key].append(node) 53 54 def remove(self, node: Element): 55 """Removes element from indexed collection if there.""" 56 57 key = node.properties[self.key] if isinstance(self.key, str) else self.key(node) 58 if key in self.indexed_tree and node in self.indexed_tree[key]: 59 self.indexed_tree[key].remove(node) 60 61 def get(self, _key: str) -> Optional[list[Element]]: 62 """Get a specific index from the indexed tree.""" 63 return self.indexed_tree.get(_key) 64 65 def map(self, modifier: Callable) -> list: 66 """Applies the passed modifier to each index. 67 68 Returns: 69 list of results generated by the modifier applied 70 to each index. 71 """ 72 result = [] 73 for value in self.indexed_tree.values(): 74 result.extend([modifier(v) for v in value]) 75 return result
Uses the given key or key generator and creates a mutable dict of key value pairs that can be easily indexed.
Nodes that don't match the condition or don't have a valid key are not indexed.
Index( key: Union[str, Callable], start: phml.nodes.AST.AST | phml.nodes.root.Root | phml.nodes.element.Element, condition: Union[NoneType, str, list, dict, Callable] = None)
19 def __init__( 20 self, key: str | Callable, start: AST | Root | Element, condition: Optional[Test] = None 21 ): 22 """ 23 Args: 24 `key` (str | Callable): Str represents the property to use as an index. Callable 25 represents a function to call on each element to generate a key. The returned key 26 must be able to be converted to a string. If none then element is skipped. 27 `start` (AST | Root | Element): The root or node to start at while indexing 28 `test` (Test): The test to apply to each node. Only valid/passing nodes 29 will be indexed 30 """ 31 from phml.utils import test, walk # pylint: disable=import-outside-toplevel 32 33 self.indexed_tree = {} 34 self.key = key 35 36 for node in walk(start): 37 if isinstance(node, Element): 38 if condition is not None: 39 if test(node, condition): 40 self.add(node) 41 else: 42 self.add(node)
Args
key
(str | Callable): Str represents the property to use as an index. Callable- represents a function to call on each element to generate a key. The returned key
- must be able to be converted to a string. If none then element is skipped.
start
(AST | Root | Element): The root or node to start at while indexingtest
(Test): The test to apply to each node. Only valid/passing nodes- will be indexed
def
add(self, node: phml.nodes.element.Element):
44 def add(self, node: Element): 45 """Adds element to indexed collection if not already there.""" 46 47 key = node.properties[self.key] if isinstance(self.key, str) else self.key(node) 48 if key not in self.indexed_tree: 49 self.indexed_tree[key] = [node] 50 51 if node not in self.indexed_tree[key]: 52 self.indexed_tree[key].append(node)
Adds element to indexed collection if not already there.
def
remove(self, node: phml.nodes.element.Element):
54 def remove(self, node: Element): 55 """Removes element from indexed collection if there.""" 56 57 key = node.properties[self.key] if isinstance(self.key, str) else self.key(node) 58 if key in self.indexed_tree and node in self.indexed_tree[key]: 59 self.indexed_tree[key].remove(node)
Removes element from indexed collection if there.
def
get(self, _key: str) -> Optional[list[phml.nodes.element.Element]]:
61 def get(self, _key: str) -> Optional[list[Element]]: 62 """Get a specific index from the indexed tree.""" 63 return self.indexed_tree.get(_key)
Get a specific index from the indexed tree.
def
map(self, modifier: Callable) -> list:
65 def map(self, modifier: Callable) -> list: 66 """Applies the passed modifier to each index. 67 68 Returns: 69 list of results generated by the modifier applied 70 to each index. 71 """ 72 result = [] 73 for value in self.indexed_tree.values(): 74 result.extend([modifier(v) for v in value]) 75 return result
Applies the passed modifier to each index.
Returns
list of results generated by the modifier applied to each index.