2024. 5. 8. 14:09ㆍDevelopment/[Kotlin] 코틀린
우선, 가장 손쉽게 리스트를 하나를 생성한다.
![](https://t1.daumcdn.net/keditor/emoticon/face/large/043.png)
리스트는 문자로 구성된 리스트로 구성한다.
var list = listOf("1", "1", "2", "3")
//[1, 1, 2, 3]
filter
list.filter { it == "1" }
// [1, 1]
list.filter { it == "2" }
// [2]
위와 같이 filter 함수에 "조건"을 걸면 조건에 해당하는 값들을 모두 리스트로 반환한다
it == "1" 이라는 조건에서 it는 list 의 항목 값을 뜻하는 일종의 예시 변수명으로 이름은 다음과 같이 원하는 이름으로 바꿀 수 있다.
list.filter { filterId -> filterId == "1" }
//it라는 이름을 filterId 라는 원하는 변수명으로 변경
find
list.find { it == "1" }
//1
find 의 경우 조건에 해당하는 값을 1개만 반환한다 (filter 함수와 다르다)
groupBy
val groupBy = list.groupBy { it }
//{1=[1, 1], 2=[2], 3=[3]}
groupBy는 조건이 같은 값을 묶어서 Map 형태로 반환하는데,
이때 조건이 단순히 "같은 값만" 묶는 식으로 하면 맵의 키가 1, 2, 3 과 같이 지정되고 이 조건에 해당하는 값들이 리스트로 들어있다
val groupByPair = list.groupBy { it == "1" }
//{true=[1, 1], false=[2, 3]}
조건을 좀 더 걸면 그 조건의 참에 해당하는 값들은 true 키에, 조건의 거짓에 해당하는 값들은 false 키로 분류되며,
각 해당하는 값들이 리스트로 들어있다.
이번에는 리스트를 단순 문자 리스트가 아니라 map 을 리스트로 가지는 리스트를 다음과 같이 만들어보자.
var map = listOf("1" to "123", "2" to "bcd", "3" to "123")
*. 코틀린의 경우 위와 같이 아주 편하게 map 형태를 "키 to 값" 과 같이 명시하여 만들수 있다.
map.groupBy { it.first }
//{1=[(1, 123)], 2=[(2, bcd)], 3=[(3, 123)]}
groupBy 함수를 map을 가지는 리스트에 적용하는 경우 위와 같이 출력할 수 있는데,
우선 it. first 에서 first 의 의미를 알기 위해서는 map 을 어떻게 반환하는지 알아야 한다.
map 의 경우 키와 값의 "쌍"으로 이루어져있는데 groupBy가 map의 키,값 쌍을
코틀린의 "Pair" 라는 클래스로 반환한다.
Pair 클래스에 대해서
public final data class Pair<out A, out B>(
val first: A,
val second: B
) : Serializable /* = Serializable */
Pair 클래스는 변수를 2개 가지고 있는데 이때 first에 해당하는 것이 map의 키, second에 해당하는 것이 map의 값이다.
따라서 it. first 는 map의 "키"를 기준으로 groupBy하라는 의미가 되며,
키가 "1", "2", "3" 이기때문에 결과가 {1=[(1, 123)], 2=[(2, bcd)], 3=[(3, 123)]} 으로 반환된다.
호오오옥시나 다음과 같이 만들면 어떻게 될까?
var map중복키 = listOf("1" to "123", "1" to "456", "2" to "bcd", "3" to "123")
map중복키.groupBy { it.first }
//과연?
결과는
{1=[(1, 123), (1, 456)], 2=[(2, bcd)], 3=[(3, 123)]}
과 같이 출력된다.
같은 키인 "1"을 가진 것이
"1" to "123", "1" to "456"
이렇게 2개이기때문이다.
*. 호오오오옥시나 어? Map은 키가 중복이 안되는거 아닌가? 라고 생각한다면, 위의 "map중복키" 라는 변수명에 속아서(?) 오해를 하면 안된다. 위의 변수는 "단순 리스트"이으로 중복값이 당연히 허용된다.
이번에는 그럼 "값"으로 조건을 먹여보면
map.groupBy { it.second }
//{123=[(1, 123), (3, 123)], bcd=[(2, bcd)]}
값이 같은 항목들끼리 묶여있는데, 이때는 키가 first로 조건을 걸었을때와 달리 "값"이 곧 키가 된다.
이번에는 다른 조건을 걸어보기 위해 값을 "숫자"로 갖는 리스트를 만들어서 조건을 걸어보자.
var mapInteger = listOf("1" to 2, "2" to 4, "3" to 1)
mapInteger.groupBy { it.second % 2 == 0 }
//{true=[(1, 2), (2, 4)], false=[(3, 1)]}
그럼 위와 같이 groupBy에 수식을 통해 해당 조건이 참과 거짓인 map이 각각 반환이 된다.
키는 true, false로 나뉜다.
groupingBy
var mapInteger = listOf("1" to 2, "2" to 4, "3" to 1)
val groupByValue = mapInteger.groupBy {
if(it.second % 2 == 0) {
"짝수"
}
else {
"홀수"
}
}
//{짝수=[(1, 2), (2, 4)], 홀수=[(3, 1)]}
val groupingByValue = mapInteger.groupingBy {
if(it.second % 2 == 0) {
"짝수"
}
else {
"홀수"
}
}
val counts = groupingByValue.eachCount()
//counts = [짝수=2, 홀수=1]
groupingBy는 조건식을 통해서 조건에 해당하는 값의 갯수를 확인할 수 있는 eachCount 함수를 제공한다.
groupBy와 다른점은 반환 값이 다르기때문에 용도에 따라 다르게 사용이 가능하다
다음 글에서는 reduce와 fold에 대해 알아보고자 한다.
var listInteger = listOf(1, 2, 3, 4, 5)
val sumTotal = listInteger.reduce { total, num -> total + num }
// sumTotal == 15
val sumTotalStart2 = listInteger.fold(2) { total, num -> total + num }
//sumTotalStart2 == 17