add filter implementation

This commit is contained in:
Jakob Ketterl 2023-05-05 22:52:12 +02:00
parent 25b229c4ba
commit 5e60bda758
2 changed files with 65 additions and 0 deletions

View file

@ -48,6 +48,34 @@ class ActiveListTransformationListener(ActiveListListener):
del self.target[change.index]
class ActiveListFilterListener(ActiveListListener):
def __init__(self, filter: callable, keyMap: list, target: "ActiveList"):
self.filter = filter
self.keyMap = keyMap
self.target = target
def onListChange(self, changes: list[ActiveListChange]):
for change in changes:
if isinstance(change, ActiveListIndexAppended):
if self.filter(change.newValue):
self.target.append(change.newValue)
self.keyMap.append(len(self.target) - 1)
elif isinstance(change, ActiveListIndexUpdated):
if change.index in self.keyMap and not self.filter(change.newValue):
idx = self.keyMap.index(change.index)
del self.target[idx]
del self.keyMap[idx]
elif change.index not in self.keyMap and self.filter(change.newValue):
# TODO insert, not append
self.target.append(change.newValue)
self.keyMap.append(len(self.target) - 1)
elif isinstance(change, ActiveListIndexDeleted):
if change.index in self.keyMap:
idx = self.keyMap.index(change.index)
del self.target[idx]
del self.keyMap[idx]
class ActiveList:
def __init__(self, elements: list = None):
self.delegate = elements.copy() if elements is not None else []
@ -82,6 +110,16 @@ class ActiveList:
self.addListener(ActiveListTransformationListener(transform, res))
return res
def filter(self, filter: callable):
res = ActiveList()
keyMap = []
for idx, val in enumerate(self):
if filter(val):
res.append(val)
keyMap.append(idx)
self.addListener(ActiveListFilterListener(filter, keyMap, res))
return res
def __setitem__(self, key, value):
if self.delegate[key] == value:
return

View file

@ -121,3 +121,30 @@ class ActiveListTest(TestCase):
transformedList = list.map(lambda x: "prefix-{}".format(x))
del list[0]
self.assertEqual(transformedList[0], "prefix-value2")
def testFilter(self):
list = ActiveList([1, 2, 3, 4, 5])
filteredList = list.filter(lambda x: x < 3)
self.assertEqual(len(filteredList), 2)
self.assertEqual(filteredList[0], 1)
self.assertEqual(filteredList[1], 2)
def testActiveFilterAppend(self):
list = ActiveList([1, 2, 3, 4, 5])
filteredList = list.filter(lambda x: x < 3)
list.append(0)
self.assertEqual(len(filteredList), 3)
self.assertEqual(filteredList[2], 0)
def testActiveFilterUpdate(self):
list = ActiveList([1, 2, 3, 4, 5])
filteredList = list.filter(lambda x: x < 3)
list[3] = 0
self.assertEqual(len(filteredList), 3)
self.assertEqual(filteredList[2], 0)
def testActiveFilterDelete(self):
list = ActiveList([1, 2, 3, 4, 5])
filteredList = list.filter(lambda x: x < 3)
del list[1]
self.assertEqual(len(filteredList), 1)