
walkmc.extensions.collections.Maps.kt Maven / Gradle / Ivy
@file:Suppress("NOTHING_TO_INLINE")
package walkmc.extensions.collections
import net.jodah.expiringmap.*
import org.checkerframework.checker.units.qual.*
import walkmc.*
import walkmc.extensions.*
import java.util.*
typealias ExpiringMapBuilder = ExpiringMap.Builder.() -> Unit
/**
* Creates a new enum map with the specified [entries].
*/
inline fun , V> enumMapOf(vararg entries: Pair): EnumMap {
val result = EnumMap(T::class.java)
result.putAll(entries)
return result
}
/**
* Creates a new empty enum map.
*/
inline fun , V> enumMapOf(): EnumMap = EnumMap(T::class.java)
/**
* Creates a new empty tree map with a optional [comparator].
*/
fun treeMapOf(comparator: Comparator? = null) = TreeMap(comparator)
/**
* Creates a new empty tree map with a optional [comparator].
*/
fun treeMapOf(
vararg elements: Pair,
comparator: Comparator? = null,
) = TreeMap(comparator).also { it.putAll(elements.toMap()) }
/**
* Converts this map to a tree map.
*/
fun , V> Map.toTreeMap() = TreeMap(this)
/**
* Converts this map to a tree map with the specified [comparator].
*/
fun Map.toTreeMap(comparator: Comparator) =
TreeMap(comparator).also { it.putAll(this) }
/**
* Creates a new empty [MutableMap] as [LinkedHashMap].
*/
inline fun newMutableMap(): MutableMap = LinkedHashMap()
/**
* Creates a new mutable map with the specified elements.
*/
inline fun newMutableMap(vararg elements: Pair): MutableMap = mutableMapOf(*elements)
/**
* Creates a new map with the specified elements.
*/
inline fun newMap(vararg elements: Pair): Map = mapOf(*elements)
/**
* Creates a new [ExpiringMap] with the specified builder.
*/
inline fun newExpiringMap(builder: ExpiringMapBuilder): ExpiringMap = ExpiringMap
.builder()
.apply(builder.cast())
.build()
/**
* Converts this [Map] in to a [ExpiringMap] with the specified builder.
*/
inline fun Map.toExpiringMap(builder: ExpiringMapBuilder): ExpiringMap =
newExpiringMap(builder)
.apply {
putAll(this@toExpiringMap)
}
/**
* Reverses this map, this is, keys will be values and values will be keys.
*/
fun Map.reverse(): Map {
val result = LinkedHashMap()
for ((key, value) in this)
result[value] = key
return result
}
/**
* Reverses this mutable map, this is, keys will be values and values will be keys.
*/
@JvmName("mutableReverse")
fun MutableMap.reverse(): MutableMap {
val result = LinkedHashMap()
for ((key, value) in this)
result[value] = key
return result
}
/**
* Finds the first value occurrence by the given [predicate] or nulls if nothing is found.
*/
inline fun Map.findValue(predicate: (V) -> Boolean): V? {
for ((_, value) in this) {
if (predicate(value))
return value
}
return null
}
/**
* Finds the last value occurrence by the given [predicate] or nulls if nothing is found.
*/
inline fun Map.findLastValue(predicate: (V) -> Boolean): V? {
var last: V? = null
for ((_, value) in this) {
if (predicate(value))
last = value
}
return last
}
/**
* Finds the first key occurrence by the given [predicate] or nulls if nothing is found.
*/
inline fun Map.findKey(predicate: (K) -> Boolean): K? {
for ((key, _) in this) {
if (predicate(key))
return key
}
return null
}
/**
* Finds the last key occurrence by the given [predicate] or nulls if nothing is found.
*/
inline fun Map.findLastKey(predicate: (K) -> Boolean): K? {
var last: K? = null
for ((key, _) in this) {
if (predicate(key))
last = key
}
return last
}
/**
* Finds the first value occurrence by the given [predicate]
* or throws a [NoSuchElementException] if nothing is found.
*/
inline fun Map.firstValue(predicate: (V) -> Boolean): V {
for ((_, value) in this) {
if (predicate(value))
return value
}
noElementError("No value found with the given predicate.")
}
/**
* Finds the last value occurrence by the given [predicate]
* or throws a [NoSuchElementException] if nothing is found.
*/
inline fun Map.lastValue(predicate: (V) -> Boolean): V {
var last: V? = null
var found = false
for ((_, value) in this) {
if (predicate(value)) {
last = value
found = true
}
}
if (!found) noElementError("No value found with the given predicate.")
return last as V
}
/**
* Finds the first value occurrence of the given [predicate] selecting by entries
* or throws a [NoSuchElementException] if nothing is found.
*/
inline fun Map.firstValueBy(predicate: (Entry) -> Boolean): V {
for (entry in this) {
if (predicate(entry))
return entry.value
}
noElementError("No value found with the given predicate.")
}
/**
* Finds the last value occurrence of the given [predicate] selecting by entries
* or throws a [NoSuchElementException] if nothing is found.
*/
inline fun Map.lastValueBy(predicate: (Entry) -> Boolean): V {
var last: V? = null
var found = false
for (entry in this) {
if (predicate(entry)) {
last = entry.value
found = true
}
}
if (!found) noElementError("No value found with the given predicate.")
return last as V
}
/**
* Finds the first value occurrence of the given [predicate] selecting by keys
* or throws a exception if nothing is found.
*/
inline fun Map.firstValueByKey(predicate: (K) -> Boolean): V {
for ((key, value) in this) {
if (predicate(key))
return value
}
noElementError("No value found with the given predicate.")
}
/**
* Finds the last value occurrence of the given [predicate] selecting by keys
* or throws a [NoSuchElementException] if nothing is found.
*/
inline fun Map.lastValueByKey(predicate: (K) -> Boolean): V {
var last: V? = null
var found = false
for ((key, value) in this) {
if (predicate(key)) {
last = value
found = true
}
}
if (!found) noElementError("No value found with the given predicate.")
return last as V
}
/**
* Finds the first key occurrence of the given [predicate]
* or throws a [NoSuchElementException] if nothing is found.
*/
inline fun Map.firstKey(predicate: (K) -> Boolean): K {
for ((key, _) in this) {
if (predicate(key))
return key
}
noElementError("No key found with the given predicate.")
}
/**
* Finds the last key occurrence of the given [predicate]
* or throws a [NoSuchElementException] if nothing is found.
*/
inline fun Map.lastKey(predicate: (K) -> Boolean): K {
for ((key, _) in this) {
if (predicate(key))
return key
}
noElementError("No key found with the given predicate.")
}
/**
* Finds the first key occurrence of the given [predicate] selecting by entries
* or throws a [NoSuchElementException] if nothing is found.
*/
inline fun Map.firstKeyBy(predicate: (Entry) -> Boolean): K {
for (entry in this) {
if (predicate(entry))
return entry.key
}
noElementError("No key found with the given predicate.")
}
/**
* Finds the last key occurrence of the given [predicate] selecting by entries
* or throws a [NoSuchElementException] if nothing is found.
*/
inline fun Map.lastKeyBy(predicate: (Entry) -> Boolean): K {
var last: K? = null
var found = false
for (entry in this) {
if (predicate(entry)) {
last = entry.key
found = true
}
}
if (!found) noElementError("No key found with the given predicate.")
return last as K
}
/**
* Finds the first key occurrence of the given [predicate] selecting by values
* or throws a [NoSuchElementException] if nothing is found.
*/
inline fun Map.firstKeyByValue(predicate: (V) -> Boolean): K {
for ((key, value) in this) {
if (predicate(value))
return key
}
noElementError("No key found with the given predicate.")
}
/**
* Finds the last key occurrence of the given [predicate] selecting by values
* or throws a [NoSuchElementException] if nothing is found.
*/
inline fun Map.lastKeyByValue(predicate: (V) -> Boolean): K {
var last: K? = null
var found = false
for ((key, value) in this) {
if (predicate(value)) {
last = key
found = true
}
}
if (!found) noElementError("No key found with the given predicate.")
return last as K
}
/**
* Performs the given [action] for each key of this map.
*/
inline fun Map.forEachKey(action: (K) -> Unit) = keys.forEach(action)
/**
* Performs the given [action] for each value of this map.
*/
inline fun Map.forEachValue(action: (V) -> Unit) = values.forEach(action)
/**
* Performs the given [action] for each key indexed of this map.
*/
inline fun Map.forEachKeyIndexed(action: (Int, K) -> Unit) = keys.forEachIndexed(action)
/**
* Performs the given [action] for each value indexed of this map.
*/
inline fun Map.forEachValueIndexed(action: (Int, V) -> Unit) = values.forEachIndexed(action)
/**
* Performs the given [action] on each key of this map.
*/
inline fun Map.onEachKey(action: (K) -> Unit) = keys.onEach(action)
/**
* Performs the given [action] on each value of this map.
*/
inline fun Map.onEachValue(action: (V) -> Unit) = values.onEach(action)
/**
* Performs the given [action] on each key indexed of this map.
*/
inline fun Map.onEachKeyIndexed(action: (Int, K) -> Unit) = keys.onEachIndexed(action)
/**
* Performs the given [action] on each value indexed of this map.
*/
inline fun Map.onEachValueIndexed(action: (Int, V) -> Unit) = values.onEachIndexed(action)
/**
* Create a sorted map of this map by natural comparator of [K].
*/
fun , V> Map.sorted() = TreeMap(this)
/**
* Create a sorted map of this map by the comparator of the comparable [K] in descending order.
*/
fun , V> Map.sortedDescending() = toTreeMap(compareByDescending { it })
/**
* Create a sorted map of this map by the given comparator comparing the keys of this map.
*/
fun Map.sortedWith(comparator: Comparator) = toTreeMap(comparator)
/**
* Create a sorted map of this map by the given comparator comparing the keys of this map.
*/
inline fun Map.sortedBy(crossinline compare: (K) -> Boolean) =
toTreeMap(compareBy(compare))
/**
* Create a sorted map of this map by the given comparator comparing the keys of this map in desceding order.
*/
fun Map.sortedWithDescending(comparator: Comparator) =
toTreeMap(comparator.reversed())
/**
* Create a sorted map of this map by the given comparator comparing the keys of this map in desceding order.
*/
inline fun Map.sortedByDescending(crossinline compare: (K) -> Boolean) =
toTreeMap(compareByDescending(compare))
/**
* Sorts this map by the natural order of [V].
* ### This not keeps the key sequence by the values.
*/
fun > Map.sortedValues() : Map {
val result = newMutableMap()
val sorted = values.sorted()
for ((index, key) in keys.withIndex())
result[key] = sorted[index]
return result
}
/**
* Sorts this map by the [valueComparator] comparing the values of this map.
* ### This not keeps the key sequence by the values.
*/
fun Map.sortedValuesWith(valueComparator: Comparator) : Map {
val result = newMutableMap()
val sorted = values.sortedWith(valueComparator)
for ((index, key) in keys.withIndex())
result[key] = sorted[index]
return result
}
/**
* Sorts this map by the [keyComparator] and [valueComparator].
* ### This not keeps the key sequence by the values.
*/
fun Map.sortedWith(
keyComparator: Comparator,
valueComparator: Comparator
) : Map {
val result = newMutableMap()
val keys = keys.sortedWith(keyComparator)
val values = values.sortedWith(valueComparator)
for (i in 0 until size)
result[keys[i]] = values[i]
return result
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy