Skip to content

Commit 5fa3115

Browse files
authored
Merge pull request #300 from linkml/optimize-applicable-classes
optimize `get_classes_by_slot()` in `schemaview.py`
2 parents 16cdeb9 + 54d9515 commit 5fa3115

File tree

2 files changed

+18
-15
lines changed

2 files changed

+18
-15
lines changed

linkml_runtime/utils/schemaview.py

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1531,29 +1531,32 @@ def slot_range_as_union(self, slot: SlotDefinition) -> List[ElementName]:
15311531
if x.range:
15321532
range_union_of.append(x.range)
15331533
return range_union_of
1534-
1535-
def get_classes_by_slot(self, slot: SlotDefinition, include_induced: bool = False) -> List[ClassDefinitionName]:
1534+
1535+
def get_classes_by_slot(
1536+
self, slot: SlotDefinition, include_induced: bool = False
1537+
) -> List[ClassDefinitionName]:
15361538
"""Get all classes that use a given slot, either as a direct or induced slot.
15371539
15381540
:param slot: slot in consideration
15391541
:param include_induced: supplement all direct slots with induced slots, defaults to False
15401542
:return: list of slots, either direct, or both direct and induced
15411543
"""
1542-
slots_list = [] # list of all direct or induced slots
1544+
classes_set = set() # use set to avoid duplicates
1545+
all_classes = self.all_classes()
15431546

1544-
for c_name, c in self.all_classes().items():
1545-
# check if slot is direct specification on class
1547+
for c_name, c in all_classes.items():
15461548
if slot.name in c.slots:
1547-
slots_list.append(c_name)
1549+
classes_set.add(c_name)
15481550

1549-
# include induced classes also if requested
15501551
if include_induced:
1551-
for c_name, c in self.all_classes().items():
1552-
for ind_slot in self.class_induced_slots(c_name):
1553-
if ind_slot.name == slot.name:
1554-
slots_list.append(c_name)
1555-
1556-
return list(dict.fromkeys(slots_list))
1552+
for c_name in all_classes:
1553+
induced_slot_names = [
1554+
ind_slot.name for ind_slot in self.class_induced_slots(c_name)
1555+
]
1556+
if slot.name in induced_slot_names:
1557+
classes_set.add(c_name)
1558+
1559+
return list(classes_set)
15571560

15581561
@lru_cache()
15591562
def get_slots_by_enum(self, enum_name: ENUM_NAME = None) -> List[SlotDefinition]:

tests/test_utils/test_schemaview.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -786,12 +786,12 @@ def test_get_classes_by_slot(self):
786786
actual_result = sv.get_classes_by_slot(slot)
787787
expected_result = ["Person"]
788788

789-
self.assertListEqual(expected_result, actual_result)
789+
self.assertListEqual(sorted(expected_result), sorted(actual_result))
790790

791791
actual_result = sv.get_classes_by_slot(slot, include_induced=True)
792792
expected_result = ["Person", "Adult"]
793793

794-
self.assertListEqual(actual_result, expected_result)
794+
self.assertListEqual(sorted(actual_result), sorted(expected_result))
795795

796796
def test_materialize_patterns(self):
797797
sv = SchemaView(SCHEMA_WITH_STRUCTURED_PATTERNS)

0 commit comments

Comments
 (0)