Объедините Publishers.Merge, но с Publishers.combineПоследнее поведение - PullRequest
0 голосов
/ 10 февраля 2020

Я сейчас пытаюсь осуществить слияние двух издателей. Но я не могу найти решение для моего варианта использования.

Я хочу объединить 2 издателя, которые выдают массив структур одного типа. Я хочу, чтобы объединенный издатель испускал значения, когда один из объединенных издателей испускает новое значение.

По сути, это был бы вариант использования для Publishers.CombineLatest, но, поскольку оба моих базовых издателя испускают значения одного и того же типа, merge здесь будет более уместным. Но Publishers.Merge не запомнит последние значения объединенных издателей.

Поэтому я хотел бы иметь поведение Publishers.CombineLatest с операцией Publishers.Merge. Есть ли что-то внутри структуры Combine, которая может выполнить такое поведение?

Грубый пример того, что должно произойти:

Definitions:

PublisherA: emits -> [Value]
PublisherB emits -> [Value]

CombinedAB: -> [Value]


PublisherA changes: CombinedAB -> [NewA, OldB]
PublisherB changes: CombinedAB -> [OldA, NewB]

let a = CurrentValueSubject<[Int], Never>(["a", "b", "c"])
let b = CurrentValueSubject<[Int], Never>(["d", "e", "f"])

let combined = Publisher.AnyThing(a, b)

combined.sink {
   print($0)
}


b.send(["g", "h", "i"])


Outputs:
["a", "b", "c", "d", "e", "f"]
["a", "b", "c", "g", "h", "i"]

Так что это в основном Publishers.CombineLatest, но без выброса кортежа (NewA, OldB), но вместо этого уже объединены, поскольку оба значения имеют одинаковый тип.

Любая помощь очень ценится.

1 Ответ

2 голосов
/ 10 февраля 2020

Предполагая, что ваша операция объединения - это просто конкатенация подмассивов, которые вы можете сделать:

let a = CurrentValueSubject<[String], Never>(["a", "b", "c"])
let b = CurrentValueSubject<[String], Never>(["d", "e", "f"])

let combined = Publishers.CombineLatest(a, b).map(+)

combined.sink {
   print($0)     //["a", "b", "c", "d", "e", "f"] and ["a", "b", "c", "g", "h", "i"]
}


b.send(["g", "h", "i"])

Я не совсем уверен, что вы имеете в виду под "уже слитым". Если вы хотите, чтобы последний испущенный массив всегда был в конце объединенного массива, вам может потребоваться оператор scan перед map(+), чтобы иметь возможность сравнивать с предыдущими выбросами и менять их местами.

...