New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Sort MutableObservableArray<Item> #376
Comments
The hard bit is mapping the let sorted = collection.map { (event: ObservableArrayEvent<String>) -> ObservableArrayEvent<String> in
event.dataSource.sorted(by: (String, String) -> Bool) // easy to sort
// The hard bit:
switch event.change{
case .inserts([Int]):break;
case .deletes([Int]):break;
case .move(Int, Int):break;
case .updates([Int]): break;
}
} Taking a look at the algorithm used in ReactiveKit 2 to see if I can do it |
Here's my rather naïve implementation: extension ObservableArray where Item: Equatable {
public func sorted(by sorter: @escaping (Item, Item) -> Bool) -> Signal<ObservableArrayEvent<Item>, NoError>{
return Signal { (observer: AtomicObserver<ObservableArrayEvent<Item>, NoError>) -> Disposable in
let disposable = DisposeBag()
var differ: MutableObservableArray<Item>! // Stores a sorted version of the datasource, generates diff events
self.observeNext(with: { (latestUpdate: ObservableArrayEvent<Item>) in
let sorted = latestUpdate.dataSource.array.sorted(by: sorter)
if differ == nil {
differ = MutableObservableArray<Item>(latestUpdate.dataSource.array)
differ
// we don't want to pass on the first .reset event containing the unsorted array
.skip(first: 1)
// pass events from the differ to the signal observer:
.observeNext(with: observer.next).dispose(in: disposable)
// create our own .reset event instead, with the sorted array:
observer.next(ObservableArrayEvent(change: .reset, source: sorted))
}
else {
guard let differ = differ else {return}
// Replace contents of differ to generate diff event for observer:
differ.replace(with: sorted, performDiff: true)
}
}).dispose(in: disposable)
return disposable
}
}
} Usage: let collection = MutableObservableArray<Int>([])
let sorted: Signal<ObservableArrayEvent<Int>, NoError> = collection.sorted { (a, b) -> Bool in
return a < b
}
sorted.observeNext { (event: ObservableArrayEvent<Int>) in
print("Received: \(event.change), array: \(event.dataSource.array)")
switch event.change {
case .reset: fallthrough
case .endBatchEditing: print("")
default: break
}
}
collection.append(10)
collection.append(3)
collection.append(2)
collection.append(1)
collection.moveItem(from: 0, to: 2)
collection.remove(at: 1)
collection.remove(at: 2) Outputs:
Whereas the output if observing the collection (unsorted) directly is:
So the difference is an overuse of the begin/endBatchEditing (coming from the internal use of Would you be interested in me submitting a pull request for this with tests, or is there another implementation path that could be better? |
updated the above to make examples better |
I'll need few days to think about this :) I agree though, it would be nice to see sorting again. |
Cool 👍🏻 |
Hey - did you have further ideas on this one? |
Hi @iandundas, I didn't get much time to work on this recently. I want to do it but not sure when I'll get time. We would need a bit more performant implementation. |
I'll watch this ticket as I'd love to see sortable arrays as well :) |
hey @srdanrasic no worries :) fingers crossed |
Are there any updates on this? By the way. awesome library! |
@srdanrasic @tonyarnold your magic is needed! :)) |
Sorting is back! |
In ReactiveKit 2 there was the rather magical ability to sort a
CollectionProperty<[Item]>
's events in-flight, as in:Similar to #335, could it be possible to add this to the roadmap for Bond (6?), to port this functionality over to the new
MutableObservableArray
type?Cheers!
The text was updated successfully, but these errors were encountered: