inline fun <T, R> Array<out T>.flatMap(
transform: (T) -> Iterable<R>
): List<R>
inline fun <T, R> Array<out T>.flatMapIndexed(
transform: (index: Int, T) -> Iterable<R>
): List<R>
fun <T> Array<out Array<out T>>.flatten(): List<T>
flatMap: 원래 배열의 모든 요소에 대해 transform을 적용한 결과를 하나의 리스트에 담아서 반환합니다.
flatMapIndexed: flatMap과 동일하지만 transform 함수에 index 인자가 추가되었습니다.
flatten: 이중배열을 풀어서 하나의 리스트에 담아서 반환합니다.
fun main() {
val array = arrayOf("one two three", "four five six")
val deepArray = arrayOf(arrayOf(1, 2, 3), arrayOf(4, 5, 6), arrayOf(7, 8, 9))
val flatMap = array.flatMap { it.split(' ') }
val flatMapIndexed = array.flatMapIndexed { idx, value ->
if (idx == 0)
value.split(' ')
else
value.toList()
}
val flatten = deepArray.flatten()
println(flatMap) // [one, two, three, four, five, six]
println(flatMapIndexed) // [one, two, three, f, o, u, r, , f, i, v, e, , s, i, x]
println(flatten) // [1, 2, 3, 4, 5, 6, 7, 8, 9]
}
inline fun <T, R> Array<out T>.fold(
initial: R,
operation: (acc: R, T) -> R
): R
inline fun <T, R> Array<out T>.foldIndexed(
initial: R,
operation: (index: Int, acc: R, T) -> R
): R
inline fun <T, R> Array<out T>.foldRight(
initial: R,
operation: (T, acc: R) -> R
): R
inline fun <T, R> Array<out T>.foldRightIndexed(
initial: R,
operation: (index: Int, T, acc: R) -> R
): R
fold: initial이 acc의 초기값이 되고, 처음부터 마지막 요소까지 operation 함수가 반복되며 그 결과가 acc로 대입됩니다. 마지막까지 순회한 후의 acc가 fold의 최종 반환값이 됩니다.
foldIndexed: fold와 같으며, operation 함수에 index 인자가 추가되었습니다.
foldRight: fold와 같으며, 마지막에서 처음까지의 순서로 순회합니다.
foldRightIndexed: foldIndexed와 같으며, 마지막에서 처음까지의 순서로 순회합니다.
fun main() {
val array = arrayOf(1, 2, 3, 4, 5, 6)
val fold = array.fold(0) { acc, value ->
print("value: $value ")
acc + value }
val foldIndexed = array.foldIndexed(0) { idx, acc, value ->
println("idx: $idx value: $value acc: $acc")
if (idx > 2)
acc + value
else
acc
}
val foldRight = array.foldRight(0) { acc, value ->
println("value: $acc")
acc + value
}
val foldRightIndexed = array.foldRightIndexed(0) { idx, value, acc ->
println("idx: $idx acc: $acc value: $value")
if (idx > 2)
acc + value
else
acc
}
println(fold) // 1 + 2 + 3 + 4 + 5 + 6 = 21
println(foldIndexed) // 4 + 5 + 6 = 15
println(foldRight) // 6 + 5 + 4 + 3 + 2 + 1 = 21
println(foldRightIndexed) // 6 + 5 + 4 = 15
}
fold와 foldRight는 value와 acc의 순서가 역순이니 주의해서 사용합시다!
inline fun <T, R> Array<out T>.fold( initial: R, operation: (acc: R, T) -> R ): R
inline fun <T, R> Array<out T>.foldRight( initial: R, operation: (T, acc: R) -> R ): R
public inline fun <T> Array<out T>.forEach(action: (T) -> Unit): Unit
inline fun <T> Array<out T>.forEachIndexed(
action: (index: Int, T) -> Unit)
forEach: 각 요소에 action을 수행합니다.
forEachIndexed: forEach와 동일하지만, action에 index 인자가 있습니다.
forEach는 각 요소에 대해서 action을 수행하지만 그 결과가 반환되지는 않습니다. 반환값이 Unit이라는 사실을 인지하고 사용해야합니다.
fun main() {
val array = arrayOf(1, 2, 3, 4, 5, 6)
array.forEach {
print("$it ") // 1 2 3 4 5 6
}
array.forEachIndexed { index, value ->
println("index: $index, value: $value")
// index: 1, value: 2
// index: 2, value: 3
// index: 3, value: 4
// index: 4, value: 5
// index: 5, value: 6
}
}
inline fun <T> Array<out T>.onEach(
action: (T) -> Unit
): Array<out T>
inline fun <T> Array<out T>.onEachIndexed(
action: (index: Int, T) -> Unit
): Array<out T>
onEach: 배열의 요소를 순회하며 action을 수행합니다. 그 후에 원본 배열을 반환합니다.
onEachIndexed: onEach와 동일하나, action에 index 인자가 있습니다.
fun main() {
val array = arrayOf(1, 2, 3, 4, 5, 6)
val onEach = array.onEach { println(it) }
println("onEach: ${onEach.contentToString()}")
// onEach: [1, 2, 3, 4, 5, 6]
val onEachIndexed = array.onEachIndexed { index, value ->
if (index > 2)
array[index] += 1
}
println("onEachIndexed: ${onEachIndexed.contentToString()}")
// onEachIndexed: [1, 2, 3, 5, 6, 7]
}
public inline fun <T> Array<out T>
.getOrElse(index: Int, defaultValue: (Int) -> T): T
fun <T> Array<out T>.getOrNull(index: Int): T?
getOrElse: 해당 인덱스에 해당하는 배열의 요소를 반환합니다. 만약, 인덱스가 배열의 범위를 넘어가면 defaultValue를 반환합니다.
getOrNull: getOrElse와 동일하지만, 인덱스가 배열의 범위를 넘어갈 경우에 null을 반환합니다.
fun main() {
val array = arrayOf(1, 2, 3, 4, 5, 6)
val getOrElseInCase = array.getOrElse(3) { "out of bound" }
val getOrNullInCase = array.getOrNull(3)
val getOrElseOutCase = array.getOrElse(-1) { "out of bound" }
val getOrNullOutCase = array.getOrNull(-1)
println(getOrElseInCase) // 4
println(getOrNullInCase) // 4
println(getOrElseOutCase) // out of bound
println(getOrNullOutCase) // null
}
inline fun <T, K> Array<out T>.groupBy(
keySelector: (T) -> K
): Map<K, List<T>>
inline fun <T, K, V> Array<out T>.groupBy(
keySelector: (T) -> K,
valueTransform: (T) -> V
): Map<K, List<V>>
inline fun <T, K, M : MutableMap<in K, MutableList<T>>> Array<out T>.groupByTo(
destination: M,
keySelector: (T) -> K
): M
inline fun <T, K, V, M : MutableMap<in K, MutableList<V>>> Array<out T>.groupByTo(
destination: M,
keySelector: (T) -> K,
valueTransform: (T) -> V
): M
inline fun <T, K> Array<out T>.groupingBy(
crossinline keySelector: (T) -> K
): Grouping<T, K>
groupBy: keySelector 함수에 의해 반환되는 키가 동일한 요소끼리 그룹지은 Map을 반환합니다. 반환된 Map은 원본 배열의 순서를 보장합니다.
groupByTo: groupBy와 동일하지만, 추가될 Map을 지정할 수 있습니다.
groupingBy: keySelector 함수에 의해 반환되는 키가 동일한 요소끼리 묶어 Grouping 객체로 반환합니다. Grouping 객체를 사용하면, 그룹된 요소들의 수를 세거나, 더하는 등의 작업을 쉽게 할 수 있고 불필요한 컬렉션의 생성을 막을 수 있습니다.
fun main() {
val array = arrayOf(1, 2, 3, 4, 5, 6)
val grouping: Grouping<Int, Int> = array.groupingBy { it % 2 }
val groupBy = array.groupBy { it % 2 }
val groupingBy = grouping.fold(0) { acc, value ->
acc + value
}
println(groupBy) // {1=[1, 3, 5], 0=[2, 4, 6]}
println(groupingBy) // {1=9, 0=12}
}
fun <T> Array<out T>.indexOf(element: T): Int
inline fun <T> Array<out T>.indexOfFirst(
predicate: (T) -> Boolean
): Int
inline fun <T> Array<out T>.indexOfLast(
predicate: (T) -> Boolean
): Int
indexOf: 배열에서 함수의 element 인자와 일치하는 요소의 인덱스를 반환합니다. 만약 일치하는 요소가 존재하지 않는다면 -1을 반환합니다.
indexOfFirst: 배열에서 predicate가 true를 반환하는 첫번째 요소를 반환합니다. 일치하는 요소가 존재하지 않으면 -1을 반환합니다.
indexOfLast: indexOfFirst와 동일하지만, 배열을 역순으로 순회합니다.
fun main() {
val array = arrayOf(1, 2, 3, 4, 5, 6)
val indexOf = array.indexOf(3)
val indexOfFirst = array.indexOfFirst {
print("$it ") // 1 2 3
it == 3
}.also { println() }
val indexOfLast = array.indexOfLast {
print("$it ") // 6 5 4 3
it == 3
}.also { println() }
println(indexOf) // 2
println(indexOfFirst) // 2
println(indexOfLast) // 2
}
infix fun <T> Array<out T>.intersect(
other: Iterable<T>
): Set<T>
intersect 함수의 인자로 들어온 컬렉션과 원본 배열에 둘 다 존재하는 인자들을 담은 Set을 반환합니다. (교집합)
반환된 Set은 원본 배열의 순서를 보장합니다.
또한 intersect는 중위함수(infix)로 선언되어있으므로 중위표현으로 함수호출이 가능합니다.
(array intersect argument)
fun main() {
val array = arrayOf(1, 2, 3, 4, 5, 6)
val list = listOf(2, 4, 6)
val intersect = array.intersect(list)
val infixIntersect = array intersect list
println(intersect) // [2, 4, 6]
println(infixIntersect) // [2, 4, 6]
}
fun <reified T : Any> Array<*>.isArrayOf(): Boolean
fun <T> Array<out T>.isEmpty(): Boolean
fun <T> Array<out T>.isNotEmpty(): Boolean
fun Array<*>?.isNullOrEmpty(): Boolean
fun main() {
val array: Array<Int> = arrayOf(1, 2, 3, 4, 5, 6)
val nullArray: Array<Int>? = null
val emptyArray: Array<Int> = arrayOf()
val isArrayOfTrue = array.isArrayOf<Int>()
val isArrayOfFalse = array.isArrayOf<Char>()
val isEmptyTrue = emptyArray.isEmpty()
val isEmptyFalse = array.isEmpty()
val isNullOrEmptyTrue = nullArray.isNullOrEmpty()
val isNullOrEmptyFalse = array.isNullOrEmpty()
println(isArrayOfTrue) // true
println(isArrayOfFalse) // false
println(isEmptyTrue) // true
println(isEmptyFalse) // false
println(isNullOrEmptyTrue) // true
println(isNullOrEmptyFalse) // false
}
fun <T, A : Appendable> Array<out T>.joinTo(
buffer: A,
separator: CharSequence = ", ",
prefix: CharSequence = "",
postfix: CharSequence = "",
limit: Int = -1,
truncated: CharSequence = "...",
transform: ((T) -> CharSequence)? = null
): A
fun <T> Array<out T>.joinToString(
separator: CharSequence = ", ",
prefix: CharSequence = "",
postfix: CharSequence = "",
limit: Int = -1,
truncated: CharSequence = "...",
transform: ((T) -> CharSequence)? = null
): String
모든 요소를 seperator 인자로 구분하고 prefix와 postfix를 앞 뒤에 붙인 문자열반환합니다.
만약 컬렉션의 크기가 크다면, limit 인자를 사용하여 몇 개의 인자만 표시할 것인지 결정할 수 있습니다. 그럼 해당하는 갯수만큼만 표시되고 이후에 truncated 인자에 해당하는 문자열이 이어붙습니다.
transform 인자를 사용하면 배열의 각 요소에 변화를 준 후 문자열로 전환할 수 있습니다.
joinTo: buffer 인자를 사용하여 반환된 문자열이 추가될 버퍼를 지정할 수 있습니다.
joinToString: 단순히 변환된 문자열만을 반환합니다.
fun main() {
val array = Array<Int>(100) { it + 1 }
val buffer = StringBuilder("this is Buffer: ")
val joinTo = array.joinTo(
buffer = buffer,
separator = ". ",
prefix = "[",
postfix = "]",
limit = 10,
truncated = "... more"
) {
(it + 1).toString()
}
val joinToString = array.joinToString(
separator = ". ",
prefix = "[",
postfix = "]",
limit = 10,
truncated = "... more") {
(it + 1).toString()
}
println(joinTo)
// this is Buffer: [2. 3. 4. 5. 6. 7. 8. 9. 10. 11. ... more]
println(joinToString)
// [2. 3. 4. 5. 6. 7. 8. 9. 10. 11. ... more]
}
fun <T> Array<out T>.last(): T
inline fun <T> Array<out T>.last(
predicate: (T) -> Boolean
): T
fun <T> Array<out T>.lastIndexOf(element: T): Int
fun <T> Array<out T>.lastOrNull(): T?
inline fun <T> Array<out T>.lastOrNull(
predicate: (T) -> Boolean
): T?
last(): 배열의 마지막 요소를 반환합니다. 배열이 비어있다면, NoSuchElementException이 발생합니다.
last(predicate): predicate가 true를 반환하는 마지막 요소를 반환합니다. 일치하는 요소가 없다면 NoSuchElementException이 발생합니다.
lastIndexOf: 배열에서 elemnet의 인자와 일치하는 마지막 요소의 인덱스를 반환합니다. 존재하지 않으면 -1을 반환합니다.
lastOrNull: last와 동일하지만 예외가 발생하지 않고, 예외 상황에 null을 반환합니다.
inline fun <T, R> Array<out T>.map(
transform: (T) -> R
): List<R>
inline fun <T, R> Array<out T>.mapIndexed(
transform: (index: Int, T) -> R
): List<R>
inline fun <T, R : Any> Array<out T>.mapNotNull(
transform: (T) -> R?
): List<R>
inline fun <T, R : Any> Array<out T>.mapIndexedNotNull(
transform: (index: Int, T) -> R?
): List<R>
inline fun <T, R, C : MutableCollection<in R>> Array<out T>.mapTo(
destination: C,
transform: (T) -> R
): C
inline fun <T, R, C : MutableCollection<in R>> Array<out T>.mapIndexedTo(
destination: C,
transform: (index: Int, T) -> R
): C
inline fun <T, R : Any, C : MutableCollection<in R>> Array<out T>.mapNotNullTo(
destination: C,
transform: (T) -> R?
): C
inline fun <T, R : Any, C : MutableCollection<in R>> Array<out T>.mapIndexedNotNullTo(
destination: C,
transform: (index: Int, T) -> R?
): C
map: 배열의 각 요소에 transform을 적용한 결과가 담긴 리스트를 반환합니다.
mapIndexed: map과 동일하나 transform에 index 인자가 존재합니다.
mapNotNull: 배열의 각 요소에 transform을 적용한 결과가 null이 아닌 요소들만 담긴 리스트를 반환합니다.
mapIndexedNotNull: mapNotNull과 동일하나 transform에 index 인자가 존재합니다.
(map...)To: destination으로 결과가 추가될 리스트를 지정할 수 있습니다.
fun main() {
val array = Array<Int>(6) { it + 1 }
val stringArray = arrayOf("123", "abc", "2345", "65p", "3245")
val map = array.map { it.toString() }
val mapIndexed = array.mapIndexed { idx, value ->
if (idx % 2 == 0)
"\"$value\""
else
value
}
val mapNotNull = stringArray.mapNotNull {
it.toIntOrNull()
}
val mapIndexedNotNull = stringArray.mapIndexedNotNull { idx, value ->
if (idx < 3) {
value.toIntOrNull()
} else {
value
}
}
println(map) // [1, 2, 3, 4, 5, 6]
println(mapIndexed) // ["1", 2, "3", 4, "5", 6]
println(mapNotNull) // [123, 2345, 3245]
println(mapIndexedNotNull) // [123, 2345, 65p, 3245]
}
inline fun <T> Array<out T>.maxOf(
selector: (T) -> Double
): Double
fun <T> Array<out T>.maxWithOrNull(
comparator: Comparator<in T>
): T?
inline fun <T, R> Array<out T>.maxOfWith(
comparator: Comparator<in R>,
selector: (T) -> R
): R
inline fun <T, R : Comparable<R>> Array<out T>.maxByOrNull(
selector: (T) -> R
): T?
maxOf: 배열의 각 요소에 selector를 적용한 후 가장 큰 값을 반환합니다. 그중 한 요소가 NaN을 반환하면 maxOf는 NaN을 반환합니다. 배열이 비어있으면 NoSuchElement 예외가 발생합니다.
maxWithOrNull: maxWith가 deprecated되고 이젠 maxWithOrNull을 사용해야합니다. maxWithOrNull은 Comparator를 인자로 받아 그 Comparator를 기준으로 가장 큰 값을 반환합니다.
maxOfWith: 배열의 각 요소에 selector를 적용한 후 그 요소들에 대해 comparator를 사용하여 비교합니다. 그 결과 가장 큰 값을 반환합니다. 배열이 비어있다면, NoSuchElement 예외가 발생합니다.
maxByOrNull: 배열의 각 요소에 selecor를 적용한 결과가 가장 큰 첫번째 요소를 반환합니다. 배열이 비어있다면 null을 반환합니다.
fun main() {
val array = arrayOf<Int>(1, 2, 3, 4, 5)
val pairArray = arrayOf("one" to 1, "two" to 2, "three" to 3)
val maxOf = array.maxOf { it }
val maxWith = array.maxWithOrNull { lhs, rhs ->
lhs - rhs
}
val maxOfWith = pairArray.maxOfWith(
comparator = { lhs, rhs ->
lhs.second - rhs.second
},
selector = { it }
)
val maxByOrNull = pairArray.maxByOrNull { it.second }
println(maxOf) // 5
println(maxWith) // 5
println(maxOfWith) // (three, 3)
println(maxByOrNull) // (three, 3)
}
Comparator?
Comparator는 compare라는 메서드를 단 하나만 가지고 있는 functional interface 입니다. 그렇기 때문에 람다식으로 인자를 전달할 수 있습니다.
(SAM 인터페이스라고도 합니다.)
inline fun <T> Array<out T>.minOf(
selector: (T) -> Double
): Double
fun <T> Array<out T>.minWithOrNull(
comparator: Comparator<in T>
): T?
inline fun <T, R> Array<out T>.minOfWith(
comparator: Comparator<in R>,
selector: (T) -> R
): R
inline fun <T, R : Comparable<R>> Array<out T>.minByOrNull(
selector: (T) -> R
): T?
max와 모두 동일하지만, 최솟값을 찾아줍니다.
fun main() {
val array = arrayOf<Int>(1, 2, 3, 4, 5)
val pairArray = arrayOf("one" to 1, "two" to 2, "three" to 3)
val minOf = array.minOf { it }
val minWith = array.minWithOrNull { lhs, rhs ->
lhs - rhs
}
val minOfWith = pairArray.minOfWith(
comparator = { lhs, rhs ->
lhs.second - rhs.second
},
selector = { it }
)
val minByOrNull = pairArray.minByOrNull { it.second }
println(minOf) // 1
println(minWith) // 1
println(minOfWith) // (one, 1)
println(minByOrNull) // (one, 1)
}
fun <T> Array<out T>.none(): Boolean
inline fun <T> Array<out T>.none(
predicate: (T) -> Boolean
): Boolean
none(): isEmpty와 같은 동작을 합니다.
none(predicate): 배열의 요소 중 predicate를 만족하는 요소가 없다면 true를 반환합니다.
fun main() {
val array = arrayOf<Int>(1, 2, 3, 4, 5)
val emptyArray = arrayOf<Int>()
val noneFalseCondition = array.none()
val noneTrueCondition = emptyArray.none()
val predicateNoneFalseCondition = array.none { it % 2 == 0 }
val predicateNoneTrueCondition = array.none { it > 6 }
println(noneFalseCondition) // true
println(noneTrueCondition) // false
println(predicateNoneTrueCondition) // true
println(predicateNoneFalseCondition) // false
}
inline fun <T> Array<out T>.partition(
predicate: (T) -> Boolean
): Pair<List<T>, List<T>>
원본 배열의 요소에 predicate가 true를 반환한 결과와 false를 반환한 결과를 두 개의 리스트에 나누어 담습니다. 이 두 리스트를 Pair로 묶어서 반환합니다.
fun main() {
val array = arrayOf<Int>(1, 2, 3, 4, 5, 6)
val partition: Pair<List<Int>, List<Int>> = array.partition { it % 2 == 0 }
val (evens: List<Int>, odds: List<Int>) = array.partition { it % 2 == 0 }
println(partition) // ([2, 4, 6], [1, 3, 5])
println(evens) // [2, 4, 6]
println(odds) // [1, 3, 5]
}
fun <T> Array<out T>.random(): T
fun <T> Array<out T>.random(random: Random): T
random(): 배열에서 임의의 요소를 반환합니다.
random(random): 지정된 난수 소스를 사용하여 배열에서 임의의 요소를 반환합니다.
배열이 비어있으면 NoSuchElementException이 발생하지만, randomOrNull을 사용하면 null을 반환합니다.
fun main() {
val array = arrayOf<Int>(1, 2, 3, 4, 5, 6)
val charBuffer = CharArray(10)
File("/dev/random")
.bufferedReader()
.read(charBuffer)
val randomSeedList = charBuffer.map { it.code.toLong() }
repeat(5) {
println(array.random())
}
println()
repeat(5) {
println(array.random(Random(randomSeedList[it])))
}
}