Sorting & Filtering with Lens
“I can’t see a way through,” said the boy. “Can you see your next step?” “Yes.” “Just take that,” said the horse.” (Charlie Mackesy, The Boy, the Mole, the Fox and the Horse)
Melanjutkan ke artikel kemarin untuk melakukan sorting dengan 2 predicate sekaligus kita perlu membuat comparator extension pada Lens seperti berikut
extension Lens where Part: Comparable {
func comparator() -> Comparator<Whole> {
return Comparator<Whole> { (lhs, rhs) in
self.get(lhs) < self.get(rhs) ?
.lt :
self.get(lhs) >. self.get(rhs) ?
.gt :
.eq
}
}
}
Kenapa untuk melakukan sorting aja kita perlu ribet-ribet menggunakan Lens sih ?
Jawabanya karena ketika kita melakukan sorting dengan predicate lebih dari satu maka sorting tidak berjalan dengan seharusnya, contoh
[//MARK: Array LoginPage]
.sorted { a, b in
return (a.title < b.title) &&
(a.credendials.usernameField.text <
b.credendials.usernameField.text)
}
.filter { a in
return a.credendials.usernameField.text != ""
}
Result dari code tersebut akan menjadi seperti, sorting menjadi kacau
Ada cara lain untuk melakukan sorting dengan lebih dari satu predicate, berikut contohnya
[//MARK: Array LoginPage]
.sorted { a, b in
if (a.title == b.title) {
return (a.credendials.usernameField.text <
b.credendials.usernameField.text)
}
return (a.title < b.title)
}
.filter { a in
return a.credendials.usernameField.text != ""
}
Resultnya akan sesuai dengan ekspektasi tapi kalo kita bisa melakukanya dengan sedikit kode mengapa tidak
Oke kita masuk ke Sorting dengan Lens
let usernameNotNullorEmpty = Predicate<LoginPage> { $0.credendials.usernameField.text != "" }let sortByTitle = LoginPage.lens.title.comparator()
let sortByUsernameText = (LoginPage.lens.credentials..CredentialBox.lens.usernameField..TextField.lens.text).comparator()[//MARK: Array LoginPage]
.sorted(by: sortByTitle <> sortByUsernameText)
.filtered(by: usernameNotNullorEmpty)