amar
amar

Reputation: 4343

Reorder the content of BehaviourRelay<Array> without emitting

I have a situation at hand. I have a designerDress:BehaviourRelay<[MyCustomObjects]> Already implemented in code which drives few UI components.

Now I have a requirement to reorder the array which is simple

let tempArray = designerDress.value
//tempArray.reorderAsperMywish()
designerDress.accept(tempArray)

But now it recreates the UI components. My question is how can I prevent or trap a particular accept from emitting?

Upvotes: 0

Views: 30

Answers (1)

Pranav Pravakar
Pranav Pravakar

Reputation: 263

This solution may work.

The model MyCustomObjects should conform to Hashable protocol.Then we can have Array Extensions which help us to create key value pairs of elements

extension Array where Element: Hashable {
    var elementsCount: [Element: Int] {
        return reduce(into: [:]) {
            $0.updateValue(($0[$1] ?? 0) + 1, forKey: $1)
        }
    }

    func containSameElements(_ array: [Element]) -> Bool {
        let firstElementsCount = elementsCount
        let secondElementsCount = array.elementsCount
        return firstElementsCount == secondElementsCount
    }
}

And finally we can do something like this for relay

designerDress
    .distinctUntilChanged { $0.containSameElements($1) }
    .disposed(by: disposeBag)

This will not trigger any element from designerDress relay if only the order changes.

Please note

  1. I don't think it is good design
  2. If the object is very big or number of objects are very large then this will create problems as it has extra computations to convert the array into dictionary and it also needs extra space

Upvotes: 1

Related Questions