Как я могу проверить все исторические значения в ReplaySubject в RxSwift?

У меня есть простая структура Foo:

struct Foo {
    let bar: String
}

Теперь я создаю неограниченное ReplaySubject из Foos:

let subject = ReplaySubject<Foo>.createUnbounded()

Как мне теперь понять, есть ли в (незавершенном) потоке Foo, чье bar было равно abc? (Это может быть 1-й, 3-й или 20-й элемент.)


person Scott Berrevoets    schedule 04.02.2019    source источник
comment
Похоже, вам просто нужен массив   -  person daltonclaybrook    schedule 04.02.2019
comment
Я вроде как знаю, но так как я сейчас в мире Rx, мне было интересно, можно ли обойтись без дублирования этой истории.   -  person Scott Berrevoets    schedule 04.02.2019


Ответы (1)


Во-первых, это какая-то сумасшедшая просьба. Вы не должны думать о том, «что было», когда работаете с Rx. Скорее вы должны думать о том, что всегда имеет место. Вы должны думать об инвариантах...

Тем не менее, приведенный ниже оператор выдаст вам индексы. Поскольку субъект способен постоянно излучать события, оператор предназначен для работы в режиме реального времени. Его можно использовать следующим образом:

let indexes = subject.indexOfElementSatisfying { $0.bar == "abc" }

Вот:

extension ObservableConvertibleType {

    /**
     Emits the index of all the values in the stream that satisfy the predicate.

     - parameter pred: The predicate that determines whether the value satisfies the condition
     - returns: An observable sequence of indexes to those elements.
     */
    func indexOfElementSatisfying(_ pred: @escaping (E) throws -> Bool) -> Observable<Int> {
        return asObservable()
            .enumerated()
            .filter { try pred($0.element) }
            .map { $0.index }
    }
}
person Daniel T.    schedule 04.02.2019
comment
Очень полезно, спасибо! Поскольку вы упомянули, что я не должен этого делать, я думаю об этом неправильно? Я пытался сохранить его как можно более высоким уровнем, чтобы передать мой фактический вариант использования, который заключается в том, что пользователь может выполнять любое количество действий, когда в конечном итоге устанавливается bar, как я могу узнать, было ли это каждый раз установленным на abc. Должен ли я тогда просто не использовать Rx для этой ситуации? - person Scott Berrevoets; 04.02.2019
comment
Сначала вы должны сформулировать вариант использования в виде (некоторой части) приложения, выводящего X, каждый раз, когда пользователь делает/вводит Y (в условиях Z), Rx ориентирован на вывод. Когда у вас есть вариант использования в этом направлении, вы можете создать цепочку Observable, которая реализует вариант использования. - person Daniel T.; 04.02.2019
comment
Например, такой вариант использования, как Button Foo, включается всякий раз, когда значение bar последнего объекта foo установлено на abc. - person Daniel T.; 04.02.2019
comment
Интересно. Я понимаю, как изменить свое мышление и почему это помогает, просто нужно немного умственной гимнастики, чтобы сделать этот конкретный случай подходящим. Я буду играть с ним, спасибо за помощь! - person Scott Berrevoets; 04.02.2019