I have two pieces of code s.t.
- one produces stream of sets of active alerts in the system.
- second consumes events of raise/fall of an alert.
assuming the first part produces the following stream
["a", "b"]
,
["c"]
,
["e", "f", "g"]
,
I want to push these as
("a", True)
,
("b", True)
,
("c", True)
,
("a", False)
,
("b", False)
,
("e", True)
,
("f", True)
,
("g", True)
,
("c", False)
.
to the second part of the system.
I can do the following
events=[["a", "b"], ["c"], ["e", "f", "g"]]
alerts = Observable\
.from_(events)\
.map(lambda x : set(x))\
.scan(lambda (prev, events), curr : (curr, {(i, True) for i in curr - prev}.union(\
{(i, False) for i in prev - curr})),\
(set(), set()))\
.map(lambda (prev, events) : events)
subject = rx.subjects.Subject()
def my_flatten(set):
for x in set:
subject.on_next(x)
subject.subscribe(lambda x : print(x))
alerts.subscribe(my_flatten)
which produces the following result, which is ok
('a', True)
('b', True)
('b', False)
('a', False)
('c', True)
('c', False)
('g', True)
('e', True)
('f', True)
But I hoped to have a solution without a subject, something like the following
events=[["a", "b"], ["c"], ["e", "f", "g"]]
alerts = Observable\
.from_(events)\
.map(lambda x : set(x))\
.scan(lambda (prev, events), curr : (curr, {(i, True) for i in curr - prev}.union(\
{(i, False) for i in prev - curr})),\
(set(), set()))\
.flat_map(lambda (prev, events) : events)
alerts.subscribe(lambda x : print(x))
alerts = Observable\ .from_(events)\ .map(lambda x : set(x))\ .scan(lambda (prev, events), curr : (curr, {(i, True) for i in curr - prev}.union({(i, False) for i in prev - curr})), (set(), set()))\ .map(lambda (prev, events) : events)
but it produces the following, which is incorrect because you cannot reconstruct active events from it, c
turns to be active at the end.
('a', True)
('b', True)
('b', False)
('a', False)
('c', False)
('c', True)
('g', True)
('e', True)
('f', True)
flat_map
does not preserve the order, do you think there is another solution?
Thank you,
Michael