컬렉션

컬렉션 (Collections)

Scala 라이브러리에는 아주 풍부한 컬렉션 클래스들이 있고, 그 클래스들은 또 많은 메서드를 갖고 있어요. 컬렉션 클래스는 불변(immutable) 형태와 가변(mutable) 형태 모두로 제공돼요.

출처: Scala 3 Book

본문

리스트 만들기

불변의 연결 리스트(linked-list) 클래스인 List를 예로 들어, 컬렉션들이 어떻게 동작하는지 맛을 보여드릴게요. 아래 예제들은 값이 채워진 List를 만드는 여러 방법을 보여줘요.

val a = List(1, 2, 3)           // a: List[Int] = List(1, 2, 3)

// Range methods
val b = (1 to 5).toList         // b: List[Int] = List(1, 2, 3, 4, 5)
val c = (1 to 10 by 2).toList   // c: List[Int] = List(1, 3, 5, 7, 9)
val e = (1 until 5).toList      // e: List[Int] = List(1, 2, 3, 4)
val f = List.range(1, 5)        // f: List[Int] = List(1, 2, 3, 4)
val g = List.range(1, 10, 3)    // g: List[Int] = List(1, 4, 7)

List 메서드들

값이 채워진 리스트가 생기면, 그 리스트에 호출할 수 있는 몇몇 메서드를 다음 예제들이 보여줘요. 이들은 모두 함수형 메서드라는 점을 눈여겨보세요. 호출 대상인 컬렉션을 변형하지 않고, 갱신된 요소를 가진 새 컬렉션을 반환한다는 뜻이에요. 각 표현식이 반환하는 결과는 각 줄의 주석에 표시했어요.

// a sample list
val a = List(10, 20, 30, 40, 10)      // List(10, 20, 30, 40, 10)

a.drop(2)                             // List(30, 40, 10)
a.dropWhile(_ < 25)                   // List(30, 40, 10)
a.filter(_ < 25)                      // List(10, 20, 10)
a.slice(2,4)                          // List(30, 40)
a.tail                                // List(20, 30, 40, 10)
a.take(3)                             // List(10, 20, 30)
a.takeWhile(_ < 30)                   // List(10, 20)

// flatten
val a = List(List(1,2), List(3,4))
a.flatten                             // List(1, 2, 3, 4)

// map, flatMap
val nums = List("one", "two")
nums.map(_.toUpperCase)               // List("ONE", "TWO")
nums.flatMap(_.toUpperCase)           // List('O', 'N', 'E', 'T', 'W', 'O')

다음 예제들은 정수 시퀀스의 값들을 합하는 데 foldLeftreduceLeft 메서드를 어떻게 쓰는지 보여줘요.

val firstTen = (1 to 10).toList            // List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

firstTen.reduceLeft(_ + _)                 // 55
firstTen.foldLeft(100)(_ + _)              // 155 (100 is a "seed" value)

Scala 컬렉션 클래스에 쓸 수 있는 메서드는 이것보다 훨씬 많아요. 나머지는 Collections 챕터와 API 문서에서 확인할 수 있어요.

튜플 (Tuples)

Scala의 튜플(tuple)은 서로 다른 타입의 값들을 한 컨테이너에 쉽게 담을 수 있게 해주는 타입이에요. 예를 들어 이 Person case class가 있다고 해요.

case class Person(name: String)

이렇게 하면 Int, String, 그리고 커스텀 Person 값을 담은 튜플을 만들 수 있어요.

val t = (11, "eleven", Person("Eleven"))

튜플이 생기면 값을 변수에 바인딩해서 접근하거나, 번호로 접근할 수 있어요.

t(0)   // 11
t(1)   // "eleven"
t(2)   // Person("Eleven")

이터랙터(extractor) 방식으로 튜플 필드를 변수 이름에 할당할 수도 있어요.

val (num, str, person) = t

// result:
// val num: Int = 11
// val str: String = eleven
// val person: Person = Person(Eleven)

튜플은 서로 다른 타입들을 작은 컬렉션 같은 구조에 담고 싶을 때 아주 유용해요. 튜플에 대한 더 자세한 내용은 Reference 문서를 참고하세요.

더 알아보기

  • "Collections" 챕터 (Scala 3 Book)
  • Collections API 문서
  • "Scala Collections" 챕터 (Scala 3 Book)