(data, *keys, default=None, max_depth=None, map_data=None, filter_func=None)
| 78 | |
| 79 | |
| 80 | def select(data, *keys, default=None, max_depth=None, map_data=None, filter_func=None): |
| 81 | def _search(data, keys, current_depth): |
| 82 | if not keys or (max_depth is not None and current_depth > max_depth): |
| 83 | return None |
| 84 | |
| 85 | current_key = keys[0] |
| 86 | remaining_keys = keys[1:] |
| 87 | |
| 88 | # Handling dictionaries |
| 89 | if isinstance(data, dict): |
| 90 | for k, v in data.items(): |
| 91 | if k == current_key: |
| 92 | if not remaining_keys: |
| 93 | if filter_func is None or filter_func(v): |
| 94 | return v |
| 95 | else: |
| 96 | return _search(v, remaining_keys, current_depth + 1) |
| 97 | result = _search(v, keys, current_depth + 1) |
| 98 | if result is not None: |
| 99 | return result |
| 100 | |
| 101 | # Handling lists |
| 102 | elif isinstance(data, list): |
| 103 | if isinstance(current_key, int): |
| 104 | # Adjust negative index |
| 105 | if current_key < 0: |
| 106 | current_key += len(data) |
| 107 | |
| 108 | if 0 <= current_key < len(data): |
| 109 | if not remaining_keys: |
| 110 | if filter_func is None or filter_func(data[current_key]): |
| 111 | return data[current_key] |
| 112 | else: |
| 113 | return _search( |
| 114 | data[current_key], remaining_keys, current_depth + 1 |
| 115 | ) |
| 116 | else: |
| 117 | for item in data: |
| 118 | result = _search(item, keys, current_depth + 1) |
| 119 | if result is not None: |
| 120 | return result |
| 121 | |
| 122 | return None |
| 123 | |
| 124 | if map_data is None: |
| 125 | map_data = lambda x: x |
| 126 | |
| 127 | if not keys: |
| 128 | result = map_data(data) if data is not None else default |
| 129 | return result |
| 130 | else: |
| 131 | result = _search(data, keys, 0) |
| 132 | result = map_data(result) if result is not None else default |
| 133 | |
| 134 | return result |
| 135 | |
| 136 | |
| 137 | # Implement Later |
no test coverage detected