aboutsummaryrefslogtreecommitdiff
path: root/tools/cru-py/cru/util/_list.py
blob: 3b4cb28f29aebbdd8dedf85f2d6ae5e432c3ffa3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
from collections.abc import Iterable, Callable
from typing import TypeVar, ParamSpec, Any, Generic

T = TypeVar("T")
R = TypeVar("R")
P = ParamSpec("P")

CanBeList = T | Iterable[T] | None


class ListOperations:

    @staticmethod
    def foreach(l: Iterable[T], *f: Callable[[T], None] | None) -> None:
        if len(f) == 0: return
        for v in l:
            for f_ in f:
                if f_ is not None:
                    f_(v)

    @staticmethod
    def transform(l: Iterable[T], *f: Callable | None) -> list[R]:
        r = []
        for v in l:
            for f_ in f:
                if f_ is not None:
                    v = f_(v)
            r.append(v)
        return r

    @staticmethod
    def transform_if(l: Iterable[T], f: Callable[[T], R] | None, p: Callable[[T], bool] | None) -> list[R]:
        return [(f(v) if f else v) for v in l if (p(v) if p else True)]

    @staticmethod
    def all(l: Iterable[T], *p: Callable[[T], bool] | None) -> bool:
        if len(p) == 0 or all(v is None for v in p):
            raise ValueError("At least one predicate is required!")
        for v in l:
            for p_ in p:
                if p_ is not None and not p_(v): return False
        return True

    @staticmethod
    def all_is_instance(l: Iterable[T], *t: type) -> bool:
        return all(type(v) in t for v in l)

    @staticmethod
    def any(l: Iterable[T], *p: Callable[[T], bool] | None) -> bool:
        if len(p) == 0 or all(v is None for v in p):
            raise ValueError("At least one predicate is required!")
        for v in l:
            for p_ in p:
                if p_ is not None and p_(v): return True
        return False

    @staticmethod
    def make(v: CanBeList[T], /, none_to_empty_list: bool = True) -> list[T]:
        if v is None and none_to_empty_list: return []
        return v if isinstance(v, Iterable) else [v]

    @staticmethod
    def remove_all_if(l: Iterable[T], *p: Callable[[], bool] | None) -> list[T]:
        def stay(v):
            for p_ in p:
                if p_ is not None and p_(): return False
            return True

        return [v for v in l if stay(v)]

    @staticmethod
    def remove_all_value(l: Iterable[T], *r) -> list[T]:
        return [v for v in l if v not in r]

    @staticmethod
    def replace_all_value(l: Iterable[T], old_value: Any, new_value: R) -> list[T | R]:
        return [new_value if v == old_value else v for v in l]


class CruList(list, Generic[T]):

    def foreach(self, *f: Callable[[T], None] | None) -> None:
        ListOperations.foreach(self, *f)

    def transform(self, *f: Callable[[T], R] | None) -> "CruList"[R]:
        return CruList(ListOperations.transform(self, *f))

    def transform_if(self, f: Callable[[T], R] | None, p: Callable[[T], bool] | None) -> "CruList"[R]:
        return CruList(ListOperations.transform_if(self, f, p))

    def all(self, *p: Callable[[T], bool] | None) -> bool:
        return ListOperations.all(self, *p)

    def all_is_instance(self, *t: type) -> bool:
        return ListOperations.all_is_instance(self, *t)

    def any(self, *p: Callable[[T], bool] | None) -> bool:
        return ListOperations.any(self, *p)

    def remove_all_if(self, *p: Callable[[]]) -> "CruList"[T]:
        return CruList(ListOperations.remove_all_if(self, *p))

    def remove_all_value(self, *r) -> "CruList"[T]:
        return CruList(ListOperations.remove_all_value(self, *r))

    def replace_all_value(self, old_value: Any, new_value: R) -> "CruList"[T | R]:
        return CruList(ListOperations.replace_all_value(self, old_value, new_value))

    @staticmethod
    def make(l: CanBeList[T]) -> "CruList"[T]:
        return CruList(ListOperations.make(l))