Refactor out the merging logic
[climbing.kerkeslager.com] / src / core / utils.py
1 def merge(xs:iter, ys:iter, x_key, y_key=None):
2     if y_key is None:
3         y_key = x_key
4
5     if isinstance(x_key, str):
6         x_attr = x_key
7         x_key = lambda x: getattr(x, x_attr)
8
9     if isinstance(y_key, str):
10         y_attr = y_key
11         y_key = lambda y: getattr(y, y_attr)
12
13     xs = iter(xs)
14     ys = iter(ys)
15
16     try:
17         x = next(xs)
18     except StopIteration:
19         x = None
20
21     try:
22         y = next(ys)
23     except StopIteration:
24         y = None
25
26     while x and y:
27         if x_key(x) < y_key(y):
28             yield x
29             try:
30                 x = next(xs)
31             except StopIteration:
32                 x = None
33         else:
34             yield y
35             try:
36                 y = next(ys)
37             except StopIteration:
38                 y = None
39
40     while x:
41         yield x
42         try:
43             x = next(xs)
44         except StopIteration:
45             x = None
46
47     while y:
48         yield y
49         try:
50             y = next(ys)
51         except StopIteration:
52             y = None
53
54