스칼라(Scala) 리스트
스칼라에서는 다음과 같이 List라는 키워드를 사용하여 리스트를 정의할 수 있다.
> val a = List(1, 2, 3)
a: List[Int] = List(1, 2, 3)
출력을 해보면 List[Int] 라고 출력되어 Int로 구성된 리스트가 만들어진 것을 알 수 있다. 또한, 다음과 같이 여러 종류의 타입으로 구성된 리스트를 만드는 것도 가능하다.
> val b = List(1, "2", 3.0)
b: List[Any] = List(1, 2, 3.0)
참고로, Any는 모든 스칼라 타입의 부모이기 때문에 Any 타입의 변수에는 모든 타입의 값을 담는 것이 가능하다.
> val a:Any = 1
> val a:Any = "1"
> val a:Any = 2.0
> val a:Any = List(1, 2, 3)
Nil과 ::
스칼라에서는 Nil(빈 리스트)과 ::(콘즈)를 통해 리스트를 구성할 수 있다.
> Nil
List()
> 1 :: Nil
List(1)
> 1 :: List(2, 3)
List(1, 2, 3)
> 1 :: (2 :: (3 :: Nil))
List(1, 2, 3)
::는 기본적으로 값 :: 리스트 형태로 사용된다. 따라서 1 :: 2와 같이 값만 가지고 사용하면 에러가 발생한다. 1 :: 2 :: Nil의 경우는 Nil이 빈 리스트이기 때문에 사용할 수 있다.
head와 tail
리스트에 있는 head라는 메서드는 리스트의 첫 번째 요소를 반환하며, tail은 첫 번째 요소를 제외한 나머지 리스트를 반환한다.
> List(1, 2, 3).head
1
> List(1, 2, 3).tail
List(2, 3)
head와 tail은 재귀 함수를 작성할 때 요긴하게 사용된다. List의 합을 구하는 재귀 함수는 다음과 같다.
def sumOfList(list: List[Int]): Int = {
if (list == Nil) 0
else list.head + sumOfList(list.tail)
}
> sumOfList(List(1, 2, 3))
6
입력 인자 List가 빈 리스트(Nil)이면 0을 반환하고, 그 이외에는 (리스트의 head 값 + 재귀 호출(리스트의 tail))을 반환한다.
연습문제
숫자로 구성된 리스트를 인자로 받아서 짝수인 숫자만 포함하는 리스트를 반환하는 filterOdd 함수를 재귀적으로 작성하라.
object Main extends App {
// filterOdd 함수 정의
def filterOdd(numbers: List[Int]): List[Int] = {
numbers match {
case Nil => Nil // 빈 리스트의 경우, 빈 리스트를 반환
case head :: tail =>
if (head % 2 == 0) head :: filterOdd(tail) // 짝수인 경우, 리스트에 추가
else filterOdd(tail) // 홀수인 경우, 리스트에 추가하지 않음
}
}
// 예시 리스트
val nums = List(1, 2, 3, 4, 5, 6)
// 함수 호출 및 결과 출력
val result = filterOdd(nums)
println(result) // 출력: List(2, 4, 6)
}
리스트에 대한 패턴 매치
리스트는 head::tail로 구성된다. 즉, head는 리스트의 첫 번째 값이고 tail은 나머지 리스트를 가리킨다. 그러면 다음과 같이 리스트의 head와 tail을 변수에 할당하는 것이 가능하다.
> val head :: tail = List(1, 2, 3, 4 5)
> head
1
> tail
List(2, 3, 4, 5)
변수 head에는 리스트의 첫 번째 값이 배정되었고, tail에는 나머지 리스트가 배정되었다. 이를 패턴 매치에 사용할 수 있다.
> val list = List(1, 2, 3)
> list match {
case Nil => println("empty")
case head :: tail => println(head)
}
1
그럼, 앞서 작성했던 List의 합을 구하는 함수를 패턴 매칭을 사용하도록 수정해 보자.
> def sumOfList(list: List[Int]): Int = {
list match {
case Nil => 0
case head :: tail => head + sumOfList(tail)
}
}
> sumOfList(List(1, 2, 3, 4, 5))
15
list가 Nil일 때와 head :: tail일 때로 구분 지어 재귀 함수를 작성하였다. 재귀 함수를 정의할 때 패턴 매치를 사용하면 좀 더 구조적이고 세련된 코드가 되는 것을 알 수 있다.
참고 서적
'프로그래밍 > 함수형 프로그래밍' 카테고리의 다른 글
스칼라(Scala) 핵심 고차 함수 - map, flatten, flatmap (2) | 2024.07.24 |
---|---|
함수를 변수로 사용하기, 함수를 반환값으로 사용하기 (1) | 2024.07.23 |
스칼라(Scala) 기본 문법에 대해서 알아보자 (3) | 2024.07.22 |
리스프(LISP) 재귀 함수 구현해보자 (4) | 2024.07.16 |
리스프(LISP) 기본 문법에 대해서 알아보자 (0) | 2024.07.10 |
댓글