Last active
April 23, 2020 09:41
-
-
Save Xinkle/4469ec2723500d84306a7725a06dbd3e to your computer and use it in GitHub Desktop.
Kotlin custom high order functions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Get 00:00:00:0000 of day in millisecond | |
*/ | |
fun Calendar.getDayStartMills(): Long = | |
this.apply { | |
set(Calendar.HOUR_OF_DAY, 0) | |
set(Calendar.MINUTE, 0) | |
set(Calendar.SECOND, 0) | |
set(Calendar.MILLISECOND, 0) | |
}.timeInMillis | |
/** | |
* Get 23:59:59:999 of day in millisecond | |
*/ | |
fun Calendar.getDayEndMills(): Long = | |
this.apply { | |
set(Calendar.HOUR_OF_DAY, 23) | |
set(Calendar.MINUTE, 59) | |
set(Calendar.SECOND, 59) | |
set(Calendar.MILLISECOND, 999) | |
}.timeInMillis |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Run let block if condition matched | |
*/ | |
inline fun <T, R> T.letIf(condition: (T) -> Boolean, block: (T) -> (R)): R? { | |
if (condition(this)) { | |
return let(block) | |
} | |
return null | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Apply filter and transform if element satisfy given condition | |
* | |
* @param condition to check | |
* @param transform to apply mapping | |
*/ | |
inline fun <T, R : Any> Iterable<T>.mapFilterIf( | |
condition: (T) -> Boolean, | |
transform: (T) -> R | |
): List<R> { | |
return ArrayList<R>().let { | |
forEach { item -> | |
if (condition.invoke(item)) { | |
it.add(transform(item)) | |
} | |
} | |
it | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Apply transform if element satisfy given condition | |
* | |
* @param condition to check | |
* @param transform to apply mapping | |
*/ | |
inline fun <T> Iterable<T>.mapIf( | |
condition: (T) -> Boolean, | |
transform: (T) -> T | |
): List<T> { | |
return ArrayList<T>().let { | |
forEach { item -> | |
if (condition.invoke(item)) { | |
it.add(transform(item)) | |
} else { | |
it.add(item) | |
} | |
} | |
it | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Pop element matched given condition | |
* | |
* @param condition to check | |
*/ | |
inline fun <T : Any> ArrayList<T>.popIf( | |
condition: (T) -> Boolean | |
): T? { | |
return firstOrNull { | |
condition(it) | |
}.let { | |
remove(it) | |
return@let it | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Pop random element from collection | |
*/ | |
fun <T : Any> ArrayList<T>.popRandom(): T { | |
return this.random().also { | |
remove(it) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Try given code block with retry count, if it exceed limit, throw exception | |
* | |
* @throws [IllegalArgumentException] if given retry count < 1 | |
*/ | |
inline fun <T> retry(retryCount: Int, block: () -> T): T { | |
for (count in 1..retryCount) { | |
return try { | |
block() | |
} catch (e: Exception) { | |
Timber.w("Retry...($count)") | |
if (count == retryCount) | |
throw e | |
else | |
continue | |
} | |
} | |
throw IllegalArgumentException("Given retry count must be bigger than 0") | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Sort collection with given order(list) | |
*/ | |
class SortingWithGivenOrder<T>( | |
private val selector: (T) -> String, | |
private val orders: List<String> | |
) : Comparator<T> { | |
constructor(selector: (T) -> String, vararg orders: String) : this(selector, orders.toList()) | |
private val ordersMap = HashMap<String, Int>().apply { | |
orders.forEachIndexed { index, s -> put(s, index) } | |
} | |
override fun compare(one: T, two: T): Int { | |
return ordersMap.getOrElse(selector(one), { ordersMap.size }) - ordersMap.getOrElse( | |
selector(two), { ordersMap.size }) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment