如何在事件列表中按时间顺序排序?

问题描述 投票:0回答:1

此代码使用 RxSwift

import RxSwift
 
struct Input {
    let loadTrigger: Observable<Void>
}

protocol UseCase {
    func getEventsLists() -> Observable<[EventsList]>
    func saveEventsList(eventsList: EventsList) -> Observable<Void>
}

struct Event {
    let creationDate: Date
}

struct EventsList {
    let events: [Event]
}

var tempEventsList: EventsList? = nil

func example(useCase: UseCase, input: Input, disposeBag: DisposeBag) {
    let events = input.loadTrigger
        .flatMapLatest {
            useCase.getEventsLists()
                .map { $0.first }
                .do(onNext: { eventsList in
                    if eventsList == nil {
                        let eventsList = EventsList(events: [])
                        useCase.saveEventsList(eventsList: eventsList)
                            .subscribe(onNext: {
                                tempEventsList = eventsList
                            })
                            .disposed(by: disposeBag)
                    } else {
                        tempEventsList = eventsList
                    }
                })
                    .map { $0?.events ?? [] }
                    .asDriverOnErrorJustComplete()
        }
}

在我的 iOS 应用程序中,我可以创建事件来显示到既定日期还剩多少。每个事件都有其创建日期。 事件按最后创建的排序(我可以手动更改顺序),因此小部件也显示最后创建的事件(我可以更改事件以手动显示)。

我希望事件列表按时间顺序自动排序,从最新到最旧。

ios swift events rx-swift
1个回答
0
投票

这个问题有简单的答案,但也有一些建议……使用 RxSwift 的一个好处是能够摆脱“厄运金字塔”。这是当你在嵌套闭包中有嵌套闭包时。

您没有利用这一点,因此为了完成工作而缩进了多达 8 个深度。这不是必需的,并且会降低可读性。让我们在回答问题时将这段代码分解成单独的作业:

首先,让我们设置一个

Observable<[EventsList]>
变量,它会在每次 loadTrigger 触发时发出一个新的事件列表数组。请注意,我们正在共享此值,因为它稍后将被多个流使用:

let eventsLists = input.loadTrigger
    .flatMapLatest { useCase.getEventsLists() }
    .share()

接下来,我们准确定义何时调用

saveEventsList(eventsLists:)
。唯一需要它的时候是 getEventsLists() 返回空数组时。据推测,这将确保下次调用时,getEventsLists() 将至少返回一个列表:

eventsLists
    .filter { $0.isEmpty }
    .map { _ in }
    .subscribe(onNext: {
        _ = useCase.saveEventsList(eventsList: EventsList(events: []))
            .subscribe()
    })
    .disposed(by: disposeBag)

现在,让我们准确地定义

tempEventsList
被分配给:

eventsLists
    .map { $0.first ?? EventsList(events: []) }
    .subscribe(onNext: { eventsList in
        tempEventsList = eventsList
    })
    .disposed(by: disposeBag)

最后,我们得到实际的 Observable 事件数组。如您所见,排序很简单:

let events = eventsLists
    .map { $0.first?.events.sorted(by: { $0.creationDate > $1.creationDate }) ?? [] }

所有的代码看起来像这样。每个代码块都是一个单独且定义明确的功能:

let eventsLists = input.loadTrigger
    .flatMapLatest { useCase.getEventsLists() }
    .share()

eventsLists
    .filter { $0.isEmpty }
    .map { _ in }
    .subscribe(onNext: {
        _ = useCase.saveEventsList(eventsList: EventsList(events: []))
            .subscribe()
    })
    .disposed(by: disposeBag)

eventsLists
    .map { $0.first ?? EventsList(events: []) }
    .subscribe(onNext: { eventsList in
        tempEventsList = eventsList
    })
    .disposed(by: disposeBag)

let events = eventsLists
    .map { $0.first?.events.sorted(by: { $0.creationDate > $1.creationDate }) ?? [] }
© www.soinside.com 2019 - 2024. All rights reserved.