[정리] Scala 정리(2) - 컬렉션
스칼라 학교!을 개인적으로 정리한 것입니다.
기본 데이터 구조
리스트
val numbers = List(1,2,3,4)
집합
val numbers = Set(1,2,3) // duplication is not allowed
튜플
val hostPort = ("localhost",80)
hostPort._1 // return "localhost"
hostPort._2 // returns 80
// pattern matching using tuple
hostPort match {
case ("localhost", port) => ...
case (host, port) => ...
}
1->2 // returns (Int, Int) = (1,2)
멥
Map(1->2)
Map("foo" -> "bar")
Map(1->2, 3->4)
옵션(Option)
어떤 객체가 존재하거나 존재하지 않는 것을 나타낸다.
scala> val numbers = Map("one" -> 1, "two" -> 2)
//numbers: scala.collection.immutable.Map[java.lang.String,Int] = Map(one -> 1, two -> 2)
scala> numbers.get("two")
//res0: Option[Int] = Some(2), key가 있는 경우
scala> numbers.get("three")
// res1: Option[Int] = None, key가 없는 경우
// None값 처리 예시
val result = res1.getOrElse(0) * 2
// 패턴매칭
val result = res1 match { case Some(n) => n * 2 case None => 0 }
함수 콤비네이터
map
numbers=List(1,2,3,4)
numbers.map((i: Int) => i * 2)
// or
def timesTwo(i: Int): Int = i * 2
numbers.map(timesTwo _)
foreach
map
과 비슷하지만 아무것도 반환하지 않는다. 즉 값의 반환이 아닌 상태 변화에 초점을 두고 있다.
numbers.foreach((i: Int) => i * 2)
filter
numbers.filter((i:Int) => i%2==0)
zip
두 리스트들의 원소들의 쌍(튜플)으로 이루어진 단일 리스트를 반환한다.
scala> List(1, 2, 3).zip(List("a", "b", "c"))
// returns res0: List[(Int, String)] = List((1,a), (2,b), (3,c))
find
주어진 함수를 만족하는 가장 첫 원소를 반환
scala> numbers.find((i: Int) => i > 5)
// res0: Option[Int] = Some(6)
drop과 dropWhile
- drop: 첫 i 개의 원소를 제거한다.
- dropWhile: 조건에 맞는 첫 원소를 제거한다. ```scala scala> numbers.drop(5) // res0: List[Int] = List(6, 7, 8, 9, 10) // 5개의 원소 제거
scala> numbers2.dropWhile( _ !=5) // res7: List[Int] = List(5, 6, 7, 8, 9, 10) // 인수로 들어온 식이 거짓이 되는 순간 까지 제거
### foldLeft, foldRight
```scala
/* foldLeft */
numbers.foldLeft(0) {
(m: Int, n: Int) => println("m: " + m + " n: " + n); m + n
}
// m: 0 n: 1 <- 초기값 왼쪽으로 들어감
// m: 1 n: 2
// m: 3 n: 3 <- m+n (이전 계산의 합이)
// m: 6 n: 4 <- =m (왼쪽 인수로 들어감)
// m: 10 n: 5
// m: 15 n: 6
// m: 21 n: 7
// m: 28 n: 8
// m: 36 n: 9
// m: 45 n: 10
// res0: Int = 55
/* foldRight */
numbers.foldRight(0) {
(m: Int, n: Int) => println("m: " + m + " n: " + n); m + n
}
// m: 10 n: 0 <- 초기값 오른쪽으로 들어감
// m: 9 n: 10
// m: 8 n: 19 <- m+n (이전 계산의 합이)
// m: 7 n: 27 <- =n (오른쪽 인수로 들어감)
// m: 6 n: 34
// m: 5 n: 40
// m: 4 n: 45
// m: 3 n: 49
// m: 2 n: 52
// m: 1 n: 54
// res0: Int = 55
flatten
리스트를 합침
scala> List(List(1, 2), List(3, 4)).flatten
// res0: List[Int] = List(1, 2, 3, 4)
flatMap
map
과 flatten
을 합친 것이다.
scala> val nestedNumbers = List(List(1, 2), List(3, 4))
// nestedNumbers: List[List[Int]] = List(List(1, 2), List(3, 4))
scala> nestedNumbers.flatMap(x => x.map(_ * 2))
// res0: List[Int] = List(2, 4, 6, 8)
// using flatten after map, result is same
scala> nestedNumbers.map((x: List[Int]) => x.map(_ * 2)).flatten
일반적인 함수 콤비네이터
fold
를 기본으로 작성될 수 있다.
def myMap(numbers: List[Int], fn: Int => Int): List[Int] = {
numbers.foldRight( List[Int]() )/* 초기값 */ {
(x: Int, xs: List[Int]) => fn(x) :: xs // ::는 리스트 합치기
}
}
Map?
val extensions = Map("steve" -> 100, "bob" -> 101, "joe" -> 201)
// _2로 직접 접근 --> BAD!
extensions.filter((namePhone: (String, Int)) => namePhone._2 < 200)
// using Pattern Matching
extensions.filter({case (name, extension) => extension < 200})
댓글남기기