added more DRY compareBy function and helper class

This commit is contained in:
James Strachan
2012-09-14 12:44:09 +01:00
parent 51122a288d
commit 9c3d1071cd
3 changed files with 18 additions and 26 deletions
+6 -6
View File
@@ -6,14 +6,14 @@ import java.util.Comparator
* Helper method for implementing [[Comparable]] methods using a list of functions * Helper method for implementing [[Comparable]] methods using a list of functions
* to calculate the values to compare * to calculate the values to compare
*/ */
inline fun <T> compareBy(a: T?, b: T?, vararg functions: Function1<T, Any?>): Int { inline fun <T> compareBy(a: T?, b: T?, vararg functions: T.() -> Any?): Int {
require(functions.size > 0) require(functions.size > 0)
if (a === b) return 0 if (a === b) return 0
if (a == null) return - 1 if (a == null) return - 1
if (b == null) return 1 if (b == null) return 1
for (fn in functions) { for (fn in functions) {
val v1 = fn(a) val v1 = a.fn()
val v2 = fn(b) val v2 = b.fn()
val diff = compareValues(v1, v2) val diff = compareValues(v1, v2)
if (diff != 0) return diff if (diff != 0) return diff
} }
@@ -47,12 +47,12 @@ public inline fun <T> compareValues(a: T?, b: T?): Int {
/** /**
* Creates a comparator using the sequence of functions used to calculate a value to compare on * Creates a comparator using the sequence of functions used to calculate a value to compare on
*/ */
public inline fun <T> comparator(vararg functions: Function1<T,Any?>): Comparator<T> { public inline fun <T> comparator(vararg val functions: T.() -> Any?): Comparator<T> {
return FunctionComparator<T>(functions) return FunctionComparator<T>(*functions)
} }
private class FunctionComparator<T>(val functions: Array<Function1<T,Any?>>): Comparator<T> { private class FunctionComparator<T>(vararg val functions: T.() -> Any?): Comparator<T> {
public override fun toString(): String { public override fun toString(): String {
return "FunctionComparator${functions.toList()}" return "FunctionComparator${functions.toList()}"
+11 -19
View File
@@ -8,7 +8,7 @@ class Item(val name: String, val rating: Int): Comparable<Item> {
fun toString() = "Item($name, $rating)" fun toString() = "Item($name, $rating)"
public override fun compareTo(other: Item): Int { public override fun compareTo(other: Item): Int {
return compareBy(this, other, {it.rating}, {it.name}) return compareBy(this, other, { rating }, { name })
} }
} }
@@ -22,43 +22,35 @@ class CompareTest {
} }
Test fun compareByNameFirst() { Test fun compareByNameFirst() {
val diff = compareBy(v1, v2, {(i: Item) -> i.name}, {(i: Item) -> i.rating}) val diff = compareBy(v1, v2, { name }, { rating })
assertTrue(diff > 0) assertTrue(diff > 0)
} }
Test fun compareByRatingFirst() { Test fun compareByRatingFirst() {
val diff = compareBy(v1, v2, {(i: Item) -> i.rating}, {(i: Item) -> i.name}) val diff = compareBy(v1, v2, { rating }, { name })
assertTrue(diff < 0)
}
Test fun compareByRatingFirstUsingItNotation() {
val diff = compareBy(v1, v2, {it.rating}, {it.name})
assertTrue(diff < 0) assertTrue(diff < 0)
} }
Test fun compareSameObjectsByRatingFirst() { Test fun compareSameObjectsByRatingFirst() {
val diff = compareBy(v1, v1, {(i: Item) -> i.rating}, {(i: Item) -> i.name}) val diff = compareBy(v1, v1, { rating }, { name })
assertTrue(diff == 0) assertTrue(diff == 0)
} }
Test fun sortUsingComparatorHelperMethod() { Test fun sortUsingComparatorHelperMethod() {
val c = comparator<Item>({it.rating}, {it.name}) val c = comparator<Item>({ rating }, { name })
println("Created comparator $c") println("Created comparator $c")
todo { val diff = c.compare(v1, v2)
// TODO needs KT-729 before this code works assertTrue(diff < 0)
val diff = c.compare(v1, v2) val items = arrayList(v1, v2)
assertTrue(diff < 0) items.sort(c)
val items = arrayList(v1, v2) println("Sorted list in rating order $items")
items.sort(c)
println("Sorted list in rating order $items")
}
} }
Test fun sortUsingCustomComparator() { Test fun sortUsingCustomComparator() {
val c = object : Comparator<Item>{ val c = object : Comparator<Item>{
override fun compare(o1: Item?, o2: Item?): Int { override fun compare(o1: Item?, o2: Item?): Int {
return compareBy(o1, o2, {(it: Item) -> it.name}, {(it: Item) -> it.rating}) return compareBy(o1, o2, { name }, { rating })
} }
override fun equals(obj: Any?): Boolean { override fun equals(obj: Any?): Boolean {
return this == obj return this == obj
@@ -115,7 +115,7 @@ class KDocConfig() {
private class LongestFirstStringComparator() : Comparator<String> { private class LongestFirstStringComparator() : Comparator<String> {
public override fun compare(s1: String?, s2: String?): Int { public override fun compare(s1: String?, s2: String?): Int {
return compareBy(s1, s2, { (s: String) -> s.length() }, { (s: String) -> s }) return compareBy(s1, s2, { length() }, { this })
} }
public override fun equals(obj : Any?) : Boolean { public override fun equals(obj : Any?) : Boolean {