I am creating a Android Application which show list of Stores. The main Recyclerview shows the list of Store
and every store object has SortingData
which holds multiple fields like minimumDistance,rating
etc.
By user selection i get a list of selected tags
which size varies on the base of user selection and want to sort the main list of stores by it.
Every selected tag holds a propery isAscending which shows that it should be sorted in Ascending or Descending order. Lets say Rating with be Descending and Minimum Distance will be ascending and so on.
I have written a custom comparator to do so, to avoid multiple if conditions inside a loop but this comparator has issues. Like, its sorting the intergers based on first digit only doubles are also not sorted well.
Below is my code
data class Store(
val name: String,
val sortingData: SortingData,
val status: String
) {
}
data class SortingData(
val averageProductPrice: Int,
val bestMatch: Double,
val deliveryCosts: Int,
val distance: Int,
val minCost: Int,
val newest: Double,
val popularity: Double,
val ratingAverage: Float
)
data class SortTag(var text: String, var key:String,var isSelected: Boolean,var isAscending:Boolean) {
}
Function
fun sortListByAdditionalTags(
list: MutableList<Store>>, selectedTags: List<SortTag>
): MutableList<Store> {
/*
Best Match -> Descending highest value on top
Newest -> Descending highest value on top
Rating Average -> Descending highest value on top
Distance -> Ascending lowest value on top
Popularity -> Descending highest value on top
Average Product Price -> Ascending lowest value on top
Delivery cost -> Ascending lowest value on top
Min cost-> Ascending lowest value on top
*/
var sorted = list
selectedTags.forEach {
sorted = list.sortedWith(
comparator = AdditionalSortComparator(
it.key,
it.isAscending
)
) as MutableList< Store
>
}
return sorted
}
Custom Sort Comparator
class AdditionalSortComparator(
private val sortProperty: String? = null,
private val isAscending: Boolean
) : Comparator<Store> {
override fun compare(o1: Store?, o2: Store?): Int {
val sortingData =
Store::class.declaredMemberProperties.firstOrNull { it.name == "sortingData" }
val s1: sortingData = o1?.let { sortingData?.get(it) } as sortingData
val s2: sortingData = o2?.let { sortingData?.get(it) } as sortingData
val calledVariable = SortingData::class.declaredMemberProperties.firstOrNull { it.name == sortProperty }
return if (calledVariable != null) {
if (calledVariable.get(s1) is Int) {
val valueFirst = calledVariable.get(s1) as Int
val valueSecond = calledVariable.get(s2) as Int
if (isAscending) valueFirst - valueSecond else valueSecond - valueFirst
} else if (calledVariable.get(s1) is Float) {
val valueFirst = calledVariable.get(s1) as Float
val valueSecond = calledVariable.get(s2) as Float
if (isAscending) valueFirst - valueSecond else valueSecond - valueFirst
} else if (calledVariable.get(s1) is Double) {
val valueFirst = calledVariable.get(s1) as Double
val valueSecond = calledVariable.get(s2) as Double
if (isAscending) abs(valueFirst-valueSecond) else abs(valueSecond-valueFirst)
}
if (isAscending) calledVariable.get(s1).toString()
.compareTo(calledVariable.get(s2).toString())
else calledVariable.get(s2).toString()
.compareTo(calledVariable.get(s1).toString())
} else {
val idProperty = Store::name
val valueFirst = idProperty.get(o1)
val valueSecond = idProperty.get(o2)
if (isAscending) valueFirst.compareTo(valueSecond) else valueSecond.compareTo(valueFirst)
}
}
}
The dependency i used for Kotlin Reflection is
implementation("org.jetbrains.kotlin:kotlin-reflect:1.7.10")
Can somebody please help me out with this, how i can achieve this functionality in an efficient and correct manner?
Aucun commentaire:
Enregistrer un commentaire