PS문제를 하나씩 풀다보니 공부가 필요한 문법에 대해서 정리한 글입니다.
저번 포스트 때
Collection은 자료구조를 편하게 다루기 위해 제공되는 라이브러리라고 했습니다.
이번 포스트에는Collection리스트의 데이터 처리를 간단하게 해주는 함수를 알아보려 한다.
collection에 데이터가 들어왔다면 데이터를 정리하고 싶은 것이다.
그럴 때 사용하는게sort이다.
sort는 정렬이 된 새로운 객체를 반환하며 기본적으로 ASC(오름차순)이다.
만약 내림차순 정렬이 필요한 경우sortByDescending()을 사용할 수 있다.
fun main() {
val a = listOf(2, 3, 1)
println( a.sorted())
println( a.sortedDescending())
val numbersMap = mapOf("key1" to 2, "key2" to 3, "key3" to 1)
println(numbersMap.toSortedMap())
}
[1, 2, 3]
[3, 2, 1]
{key1=2, key2=3, key3=1}
해당 예제의 결과를 보면 위 순서대로 나올 것이다.
sorted()함수는a의 리스트 오름차순의 결과를 얻고
sortedDescending()함수는 내림차순 결과를 얻는다.
또한map에 대해서는String인key를 기준으로 오름차순한 결과를 얻고 있다.
저번 포스트에서
map을 다뤘었는데 맵을 다른 방식으로 다뤄보겠다.
fun main() {
val a : List<Int> = listOf(1, 2, 3)
val b = a.map { it * 10 }
println(b)
println(a.map { it * 10 })
}
이번에는 Collection을 구성하는 각 요소들에 대해 특정 표현식에 의거하여
새로운 Collection을 반환하는 방법이다.
a리스트에 10을 곱하는 표현식을 넣어준다.
그러면 변형을 거친 새로운 리스트b가 반환되며
it키워드를 통해 각 요소의 값에 접근할 수 있습니다.
forEach()는 요소들을 하나씩 출력하고 싶을 때 사용한다.
또한forEachIndexed()는 하나씩 출력한 값에 번호를 매겨주는 역할을 하며
0부터 시작한다.
fun main() {
val a : List<String> = listOf("abc", "def", "hij")
a.forEach{ println(it) }
a.forEachIndexed { index, c -> println("$index : $c") }
}
abc
def
hij
0 : abc
1 : def
2 : hij
다음 실행결과는 위와 같으며 이는 문자열 타입이라면 값을 하나씩 출력 시켜줄 것 이다.
filter는 특정 조건에 부합하는 요소만 걸러내서
새로운 collection을 반환해주는 함수이다.
예를 들어 Int형 리스트에서 짝수만 걸러내고 싶다고 생각해보자.
fun main(){
val a : List<Int> = listOf(1, 2, 3, 4, 5, 6)
val b = a.filter { it % 2 == 0 }
println(b)
}
[2, 4, 6]
그렇다면
.filter를 사용해 특정 표현식을 2로 나눴을 때 0이 되는 값을 가져오라는 조건을 걸었다.
표현식에 의거하여 짝수만 출력될 것이다.
filterValues는 Map의 value를 기준으로 필터링하는 함수이다.
주어진 조건(람다 표현식)을 만족하는 value를 가진 key-value 쌍만 포함하는
새로운 Map을 반환한다.
fun main() {
val map = mapOf("a" to 1, "b" to 2, "c" to 1, "d" to 3)
val filteredMap = map.filterValues { it > 1 }
println(filteredMap)
}
{b=2, d=3}
find()는filter와 다르게 최초로 조건에 부합하는 값을 반환해준다.
만약 내가 찾는 조건의 값이 없다면null을 반환할 것이다.
반대로findLast()함수는 조건에 부합하는 값 중 가장 마지막의 값을 가져온다.
이와 비슷한 함수로first(),last(),firstOrNull(),lastOrLull()등이 있다.
fun main() {
val a : List<Int> = listOf(1, 2, 3, 4, 5, 6)
val b = a.find { it % 2 == 0}
val c = a.findLast { it % 2 == 0 }
println("find : $b findLast : $c")
}
find : 2 findLast : 6
all은 조건을 만족하는 값이 하나라도 있을 때 true를 반환하고
any는 모든 값이 조건을 만족해야 ture를 반환한다.
none은 모든 조건이 만족하지 않을 때 true를 반환하니 차이점을 잘 알아두자.
fun main() {
val a : List<Int> = listOf(1, 2, 3, 4, 5, 6)
if (a.any { it % 2 == 0 }) {
println("짝수 데이터가 존재합니다.")
}
if (a.all { it % 2 == 0 }){
println("모든 데이터가 짝수 입니다!")
} else {
println("홀수 데이터도 존제합니다.")
}
if (a.none { it > 7 } ){
println("7보다 큰 데이터는 없습니다. ")
}
}
짝수 데이터가 존재합니다.
홀수 데이터도 존제합니다.
7보다 큰 데이터는 없습니다.
flatMap은 collection을 구성하는 요소를
내가 특정 표현식을 만들었을 때 그 표현식에 맞는 새로운 collection을 만들어 줄 것이다.
fun main() {
val a : List<Int> = listOf(1, 2, 3)
val flatA = a.flatMap { listOf( it * 3 ) }
println(flatA)
val flatList = a.flatMap { listOf(it * 3, it * 4) }
println(flatList)
}
[3, 6, 9]
[3, 4, 6, 8, 9, 12]
만약 표현식이 하나라면 그에 해당하는 collection을 출력할 것이고
두 개 이상이라면 표현식에 대한 리스트들이 모두 들어갈 것이다.
getOrElse는 인덱스 값을 참조 했을 때 해당 인덱스 값이 없을 경우
스코프 안의 코드를 실행한다.
fun main() {
val a : List<Int> = listOf(1, 2, 3, 4, 5, 6)
println(a.getOrElse(2) { 10 })
println(a.getOrElse(10) { println("10번째 요소는 없습니다") })
}
3
10번째 요소는 없습니다
첫 번째 결과는 2번째 인덱스가 있음으로 인덱스 값 3이 잘 나온 모습이고
두 번째 결과는 10번째 인덱스가 없기에 else 결과를 출력한 모습이다.
GroupBy는 키와 키에 해당하는 요소들을 리스트로 묶은 맵을 반환한다.
이 함수는 컬렉션의 각 요소에 대해 키를 추출하여 그룹화하고
각 그룹은 해당 키와 일치하는 요소들의 리스트로 표현된다.
fun main() {
val arr : List<String> = listOf("apple", "banana", "cherry", "date", "elderberry")
val arrLength = arr.groupBy { it.length }
println(arrLength)
}
{5=[apple], 6=[banana, cherry], 4=[date], 10=[elderberry]}
위 예제는 문자열의 길이에 따라 그룹화하여 맵으로 반환한 결과이다.
collection을 사용하면서 유용하게 사용할 수 있는 함수들을 정리해보았다.
아직 정리해야할 함수들이 많다.
성공적인 cs문제 풀이를 위해 더 정리할 것이다.