Xantier - Kotlin Collection Extensions
Xantier - Kotlin Collection Extensions
Xantier - Kotlin Collection Extensions
Creating Collections
Arrays
Lists
Sets
Maps
Empty Map val emptyMap: Map<String, Int> = emptyMap() Or mapOf() / hashMapOf() / linkedMapOf()
Operators
Iterables
Plus intList + 1 [1, 2, 3, 1] Returns a new iterables with old values + added one
Plus (Iterable) intList + listOf(1, 2, 3) [1, 2, 3, 1, 2, 3] Return a new iterables with old values + values from added iterable
Minus intList - 1 [2, 3] Returns a new iterables with old values - subtracted one
Operators (cont)
Minus (Iterable) intList - listOf(1, 2) `[3] Returns a new iterables with old values - values from
subtracted iterable
Maps
Plus aMap + Pair("Hi", 2) {hi=1, hello=2, Returns new map with old map values + new Pair. Updates
Goodbye=3} value if it differs
Plus (Map) aMap + mapOf(Pair("hello", 2), {hi=1, hello=2, Returns new map with old map values + Pairs from added
Pair("Goodbye", 3) Goodbye=3} map. Updates values if they differ.
Minus (Map) aMap - listOf("hello", "hi") {} Takes in an iterable of keys and removes if found
Mutables
Minus Assign mutableList -= 2 [1, 3] Mutates the list, removes element if found. Returns boolean
Plus Assign mutableList += 2 [1, 3, 2] Mutates the list, adds element. Returns boolean
Minus Assign mutableMap.minusAssign("hello") {hi=1} Takes in key and removes if that is found from the mutated
(MutableMap) map. Returns boolean. Same as -=
Plus Assign mutableMap.plusAssign("Goodbye" {hi=1, Goodbye=3} Takes in key and adds a new pair into the mutated map.
(MutableMap) to 3) Returns boolean. Same as +=
Transformers
Associate intList.associate { {1=1, 2=2, Returns a Map containing key-value pairs created by lambda
Pair(it.toString(), it) } 3=3}
Map intList.map { it + 1 } [2,3,4] Returns a new list by transforming all elements from the initial
Iterable.
MapNotNull intList.mapNotNull { null } [] Returned list contains only elements that return as not null from
the lamdba
Transformers (cont)
MapIndexed intList.mapIndexed { idx, [2,4,5] Returns a new list by transforming all elements from the initial Iterable.
value -> Lambda receives an index as first value, element itself as second.
if (idx == 0) value + 1
else value + 2 }
MapKeys aMap.mapKeys { pair -> {hi, mate=1, Transforms all elements from a map. Receives a Pair to lambda, lamdba
pair.key + ", mate" } hello, mate=2} return value is the new key of original value
MapValues aMap.mapValues { pair -> {hi=3, hello=4} Transforms all elements from a map. Receives a Pair to lambda, lamdba
pair.value + 2 }) return value is the new value for the original key.
SortedByDe intList.sortedByDescendin [3,2,1] Sorts descending based on what lambda returns. Lamdba receives the value
scending g { it } itself.
SortedWith intList.sortedWith(Compar [3,1,2] Takes in a Comparator and uses that to sort elements in Iterable.
ator<Int> { x, y ->
when {
x == 2 -> 1
y == 2 -> -1
else -> y - x
}
})
Transformers (cont)
Flatten listOf(intList, [2,3,4,1] Takes elements of all passed in collections and returns a collection with all
aSet).flatten() those elements
FlatMap listOf(intList, [2,3,4,1] Used for Iterable of Iterables and Lambdas that return Iterables. Transforms
with just aSet).flatMap { it } elements and flattens them after transformation.
return
FlatMap listOf(intList, [2,3,4,2] FlatMap is often used with monadic containers to fluently handle context, errors
with aSet).flatMap { iterable: and side effects.
transform
Iterable<Int> ->
iterable.map { it + 1 }
}
Zip listOf(3, 4).zip(intList) [(3,1), Creates a list of Pairs from two Iterables. As many pairs as values in shorter of
(4,2)] the original Iterables.
Zip with listOf(3, 4).zip(intList) { [(1,3), Creates a list of Pairs from two Iterables. As many pairs as values in shorter of
predicate firstElem, secondElem -> (2,4)] the original Iterables. Lambda receives both items on that index from Iterables.
Pair(firstElem - 2,
secondElem + 2)
}
Unzip listOf(Pair("hi", 1), Pair([hi, Reverses the operation from zip. Takes in an Iterable of Pairs and returns them
Pair("hello", 2)).unzip() hello], as a Pair of Lists.
[1,2])
Aggregators
Fold intList.fold(10) { accumulator, 16 Accumulates values starting with initial and applying operation from left to right.
value -> (10+1+2 Lambda receives accumulated value and current value.
FoldInd intList.foldIndexed(10) { idx, 13 Accumulates values starting with initial and applying operation from left to right.
exed accumulator, value -> (10+1+2) Lambda receives index as the first value.
Aggregators (cont)
FoldRight intList.foldRight(10) { 16 Accumulates values starting with initial and applying operation from right to left.
accumulator, value -> (10+3+2 Lambda receives accumulated value and current value.
Reduce intList.reduce { accumulator, 6 Accumulates values starting with first value and applying operation from left to
value -> (1+2+3) right. Lambda receives accumulated value and current value.
accumulator + value }
ReduceRig intList.reduceRight { 6 Accumulates values starting with first value and applying operation from right to
ht accumulator, value -> (3+2+1) left. Lambda receives accumulated value and current value.
accumulator + value }
Grouping
GroupBy intList.groupBy { value -> 2 } {2=[1, Uses value returned from lamdba to group elements of the Iterable. All values
2, 3]} whose lambda returns same key will be grouped.
Aggregators (cont)
GroupBy intList.groupBy({ it }, { it + 1 }) {1= Same as group by plus takes another lambda that
(With new [2], can be used to transform the current value
values)
2=
[3],
3=
[4]}
GroupByTo val mutableStringToListMap = mapOf("first" to 1, {1= Group by first lambda, modify value with second
"second" to 2) [11], lambda, dump the values to given mutable map
2=
mutableStringToListMap.values.groupByTo(mutableMapOf<Int,
[12]}
MutableList<Int>>(), { value: Int -> value }, { value ->
value + 10 })
accumulator + element }
Grouping > intList.groupingBy { "key" } {key Create a grouping by a lambda, aggregate each
Aggregate .aggregate({ key, accumulator: String?, element, isFirst =123} group. Lambda receives all keys, nullable
accumulator and the element plus a flag if value is
->
the first on from this group. If isFirst -->
when (accumulator) {
accumulator is null.
null -> "$element"
else -> accumulator + "$element"
}
})
Aggregating
Aggregators (cont)
Min intList.min() 1 Minimum value in the list. Only for Iterables of Comparables.
MinBy intList.minBy { it * 3 } 1 Minimum value returned from lambda. Only for Lambdas returning
Comparables.
SumBy intList.sumBy { if(it == 3) 6 else 9 Summation of values returned by passed in lambda. Only for lambdas returning
it }) (1+2+6) numeric values.
SumByDou intList.sumByDouble { 6.0 Summation to Double values. Lambdareceives the value and returns a Double.
ble it.toDouble() }
Filtering
Take intList.take(2) [1,2] Take n elements from Iterable. If passed in number larger than
list, full list is returned.
TakeLastW intList.takeLastWhile { it < 3 } [] Last element already satisfies this condition --> empty
hile
Drop intList.drop(2) [3] Drop n elements from the start of the Iterable.
ElementAt intList.elementAt(2) 3 Retrieve element at his index. Throws IndexOutOfBounds if element index doesn't
exist
ElementAtOrElse intList.elementAtOrElse( 4 Retrieve element at his index or return lambda value if element index doesn't exist.
13) { 4 }
ElementAtOrNull intList.elementAtOrNull( null Retrieve element at his index or return null if element index doesn't exist.
666)
Get intList[2] 3 Shorthand and preferred way for the one above
GetOrDefault aMap.getOrDefault("HI", 4 Get value or return the value returned from lambda
4)
GetOrPut mutableMap.getOrPut("HI" 5 MutableMap only. Returns the the value if it exist, otherwise puts it and returns put
) { 5 } value.
Finding
BinarySearch intList.binarySearch(2) 1 Does a binary search through the collection and returns the index of the element if
found. Otherwise returns negative index.
Find intList.find { it > 1 } 2 First element satisfying the condition or null if not found
FindLast intList.findLast { it > 1 } 3 Last element satisfying the condition or null if not found
First with predicate intList.first { it > 1 } 2 Same as find but throws NoSuchElementException if not
found
FirstOrNull with intList.firstOrNull { it > 1 } 2 Throw safe version of first(() -> Boolean).
predicate
IndexOf intList.indexOf(1) 0
Last with predicate intList.last { it > 1 } 3 Throws NoSuchElementException if none found satisfying
the condition.
LastIndexOf intList.lastIndexOf(2) 1
LastOrNull with intList.lastOrNull { it > 1 } 3 Throw safe version of last(() -> Boolean) .
predicate
OrEmpty intList.orEmpty() [1, 2[, 3] Returns itself or an empty list if itself is null.
Checks
<3 Kotlin