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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
# comparator.py
from __future__ import annotations
from typing import Callable, Optional, Union
class Comparator:
@classmethod
def comparing(cls, key_extractor: Callable[[object], object], comparator: Comparator=None) -> Comparator:
if comparator is not None:
return KeyComparator(_key_extractor=key_extractor, _key_comparator=comparator)
else:
return KeyComparator(_key_extractor=key_extractor, _key_comparator=_natural_order_comparator)
@classmethod
def natural_order(cls):
return _natural_order_comparator
@classmethod
def reverse_order(cls) -> Comparator:
return ReversedOrderComparator(_natural_order_comparator)
def then_comparing(
self,
param: Union[Callable[[object], object], Comparator],
key_comparator: Optional[Comparator]=None
) -> Comparator:
if key_comparator is not None:
return ThenComparingComparator(
_base_comparator=self,
_key_extractor=param,
_key_comparator=key_comparator
)
if isinstance(param, Comparator):
return ThenComparingComparator(
_base_comparator=self,
_key_extractor=_identity_func,
_key_comparator=param
)
return ThenComparingComparator(
_base_comparator=self,
_key_extractor=param,
_key_comparator=_natural_order_comparator
)
def reversed(self) -> Comparator:
return ReversedOrderComparator(_base_comparator=self)
def nullsFirst(self) -> Comparator:
return NullComparator(_base_comparator=self, _null_first=True)
def nullsLast(self) -> Comparator:
return NullComparator(_base_comparator=self, _null_first=False)
def compare(self, o1, o2) -> int:
raise NotImplementedError("Do not raw-use `Compartor` class.")
def equals(self, o1, o2) -> bool:
return self.compare(o1, o2) == 0
class NaturalOrderComparator(Comparator):
def compare(self, o1, o2) -> int:
if o1 < o2: return -1
if o1 > o2: return 1
return 0
class ReversedOrderComparator(Comparator):
def __init__(self, _base_comparator: Comparator) -> None:
self._base_comparator = _base_comparator
def compare(self, o1, o2) -> int:
return -1 * self._base_comparator.compare(o1, o2)
class ThenComparingComparator(Comparator):
def __init__(
self,
*,
_base_comparator: Comparator,
_key_extractor: Callable[[object], object],
_key_comparator: Comparator,
) -> None:
self._base_comparator = _base_comparator
self._key_extractor = _key_extractor
self._key_comparator = _key_comparator
def compare(self, o1, o2) -> int:
base_result = self._base_comparator.compare(o1, o2)
if base_result != 0: return base_result
return self._key_comparator.compare(self._key_extractor(o1), self._key_extractor(o2))
class KeyComparator(Comparator):
def __init__(self, *, _key_extractor: Callable[[object], object], _key_comparator: Comparator) -> None:
self._key_extractor = _key_extractor
self._key_comparator = _key_comparator
def compare(self, o1, o2) -> int:
return self._key_comparator.compare(self._key_extractor(o1), self._key_extractor(o2))
class NullComparator(Comparator):
def __init__(self, *, _base_comparator: Comparator, _null_first: bool) -> None:
self._base_comparator = _base_comparator
self._null_first = _null_first
def compare(self, o1, o2) -> int:
if o1 is None and o2 is None: return 0
if o1 is None: return -1 if self._null_first else 1
if o2 is None: return 1 if self._null_first else -1
return self._base_comparator.compare(o1, o2)
_identity_func = lambda x: x
_natural_order_comparator = NaturalOrderComparator()
|