Reputation: 789
So i have this strucuture that i use to hold data in that will feed a kotlin/js table
data class TableData<T : Any>(
var items: List<T>,
var fieldList: MutableList<KProperty1<T, Comparable<*>>> = mutableListOf(),
) : Iterable<T> {
override fun iterator() = items.iterator()
fun handleSortRequest(incoming: KProperty1<T, Comparable<*>>) {
fieldList.add(incoming)
fieldList.reverse()
items = items.sortedWith(compareBy(*fieldList.toTypedArray()))
}
}
and it works great, i am able to sort each column via something like
sort(Meal::calories)
I would like to expand upon it by adding arrows to the columns for ascending and descending like many of the popular data tables, is this possible? How would i do it.
my test class is
data class Meal(
val calories: Int,
val salad: String,
val mainCourse: String,
val desert: String,
)
and i feed the table with this list of meals.
val mealList = listOf(
Meal(calories = 90, salad = "Fruit Salad", mainCourse = "Pork", desert = "cookies"),
Meal(calories = 10, salad = "Shrimp Salad", mainCourse = "Burgers", desert = "cookies"),
Meal(calories = 30, salad = "Tuna Salad", mainCourse = "Chicken", desert = "pie"),
Meal(calories = 40, salad = "Cobb Salad", mainCourse = "Steak", desert = "jello"),
Meal(calories = 40, salad = "Caesar Salad", mainCourse = "Salmon", desert = "pudding"),
Meal(calories = 40, salad = "Potato Salad", mainCourse = "Hot Dogs", desert = "cake"),
Meal(calories = 20, salad = "Garden Salad", mainCourse = "Eggs", desert = "ice cream"),
)
Upvotes: 0
Views: 1167
Reputation: 7892
Obviously, you need to pass another parameter to your handleSortRequest
method, specifying the sort direction. Also, you need to change the type of items stored in fieldList
to store selectors alongside with sort direction.
Now, a comparator could be built from this data:
data class TableData<T : Any>(
var items: List<T>,
var fieldList: MutableList<Pair<KProperty1<T, Comparable<*>>, Boolean>> = mutableListOf(),
) : Iterable<T> {
override fun iterator() = items.iterator()
fun handleSortRequest(incoming: KProperty1<T, Comparable<*>>, isAscending: Boolean = true) {
fieldList.add(incoming to isAscending)
fieldList.reverse()
val comparator = fieldList
.map { (selector, isAsc) -> if (isAsc) compareBy(selector) else compareByDescending(selector) }
.reduce { acc, x -> acc.thenComparing(x) }
items = items.sortedWith(comparator)
}
}
Upvotes: 1