1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
package at.hannibal2.skyhanni.utils
import java.util.Collections
import java.util.WeakHashMap
import java.util.concurrent.ConcurrentLinkedQueue
object CollectionUtils {
fun <E> ConcurrentLinkedQueue<E>.drainTo(list: MutableCollection<E>) {
while (true)
list.add(this.poll() ?: break)
}
// Let garbage collector handle the removal of entries in this list
fun <T> weakReferenceList(): MutableSet<T> = Collections.newSetFromMap(WeakHashMap<T, Boolean>())
fun <T> MutableCollection<T>.filterToMutable(predicate: (T) -> Boolean) = filterTo(mutableListOf(), predicate)
fun <T> List<T>.indexOfFirst(vararg args: T) = args.map { indexOf(it) }.firstOrNull { it != -1 }
infix fun <K, V> MutableMap<K, V>.put(pairs: Pair<K, V>) {
this[pairs.first] = pairs.second
}
// Taken and modified from Skytils
@JvmStatic
fun <T> T.equalsOneOf(vararg other: T): Boolean {
for (obj in other) {
if (this == obj) return true
}
return false
}
fun <E> List<E>.getOrNull(index: Int): E? {
return if (index in indices) {
get(index)
} else null
}
fun <T : Any> T?.toSingletonListOrEmpty(): List<T> {
if (this == null) return emptyList()
return listOf(this)
}
fun <K> MutableMap<K, Int>.addOrPut(key: K, number: Int): Int =
this.merge(key, number, Int::plus)!! // Never returns null since "plus" can't return null
fun <K> MutableMap<K, Long>.addOrPut(key: K, number: Long): Long =
this.merge(key, number, Long::plus)!! // Never returns null since "plus" can't return null
fun <K> MutableMap<K, Double>.addOrPut(key: K, number: Double): Double =
this.merge(key, number, Double::plus)!! // Never returns null since "plus" can't return null
fun <K, N : Number> Map<K, N>.sumAllValues(): Double {
if (values.isEmpty()) return 0.0
return when (values.first()) {
is Double -> values.sumOf { it.toDouble() }
is Float -> values.sumOf { it.toDouble() }
is Long -> values.sumOf { it.toLong() }.toDouble()
else -> values.sumOf { it.toInt() }.toDouble()
}
}
fun List<String>.nextAfter(after: String, skip: Int = 1) = nextAfter({ it == after }, skip)
fun List<String>.nextAfter(after: (String) -> Boolean, skip: Int = 1): String? {
var missing = -1
for (line in this) {
if (after(line)) {
missing = skip - 1
continue
}
if (missing == 0) {
return line
}
if (missing != -1) {
missing--
}
}
return null
}
fun <K, V> Map<K, V>.editCopy(function: MutableMap<K, V>.() -> Unit) =
toMutableMap().also { function(it) }.toMap()
fun <T> List<T>.editCopy(function: MutableList<T>.() -> Unit) =
toMutableList().also { function(it) }.toList()
fun <K, V> Map<K, V>.moveEntryToTop(matcher: (Map.Entry<K, V>) -> Boolean): Map<K, V> {
val entry = entries.find(matcher)
if (entry != null) {
val newMap = linkedMapOf(entry.key to entry.value)
newMap.putAll(this)
return newMap
}
return this
}
fun <E> MutableList<List<E>>.addAsSingletonList(text: E) {
add(Collections.singletonList(text))
}
fun <K, V : Comparable<V>> List<Pair<K, V>>.sorted(): List<Pair<K, V>> {
return sortedBy { (_, value) -> value }
}
fun <K, V : Comparable<V>> Map<K, V>.sorted(): Map<K, V> {
return toList().sorted().toMap()
}
fun <K, V : Comparable<V>> Map<K, V>.sortedDesc(): Map<K, V> {
return toList().sorted().reversed().toMap()
}
}
|