List의 메소드에 대한 설명이다.
head 메소드는 리스트의 첫 번째 원소를 리턴하지만, tail 메소드는 head 메소드에서 리턴하는 값을 제외한 나머지를 리턴한다(나는 언제나 이 부분이 어색하다). isEmpty 메소드는 List가 비어 있는지 확인한다.
val list = List(1,2,3)
println(list.head)
println(list.tail)
println(list.isEmpty)
결과는 다음과 같다.
1
List(2, 3)
false
리스트 소스를 보면, 리스트의 멤버 변수는 다음과 같다.
def isEmpty: Boolean
def head: A
def tail: List[A]
빈 리스트에 isEmpty 메소드를 호출하고 head 메소드를 호출해본다.
val list = List()
println(list.isEmpty)
println(list.head)
결과는 다음과 같다. head에 기본적으로 Nil이 저장되기때문에 관련 에러가 발생한다.
true
Exception in thread "main" java.util.NoSuchElementException: head of empty list
at scala.collection.immutable.Nil$.head(List.scala:420)
at scala.collection.immutable.Nil$.head(List.scala:417)
Nil을 할당하면, head메소드를 호출할 수 있다.
val list2 = Nil
println(list2.head)
결과는 다음과 같다.
Exception in thread "main" java.util.NoSuchElementException: head of empty list
at scala.collection.immutable.Nil$.head(List.scala:420)
case object Nil extends List[Nothing] {
val list = List(1,2,3)
println(list.tail.tail)
println(list.tail.tail.tail)
println(list.tail.tail.tail.tail)
결과는 다음과 같은 Exception이 발생된다.
Exception in thread "main" java.lang.UnsupportedOperationException: tail of empty list
at scala.collection.immutable.Nil$.tail(List.scala:422)
at scala.collection.immutable.Nil$.tail(List.scala:417)
head, tail과 비슷한 last와 init이 있다.
val list = List(1,2,3)
println(list.init)
println(list.last)
결과는 다음과 같다.
List(1, 2)
3
리스트의 length 메소드는 리스트의 길이를 리턴한다.
val list = List(1,2,3)
println(list.length)
결과는 다음과 같다.
3
리스트의 reverse 메소드이다.
val list = List(1,2,3)
println(list.reverse)
결과는 다음과 같다.
List(3, 2, 1)
리스트의 drop 메소드이다. drop(1)은 처음부터 첫 번째 엘리먼트까지 버리고 나머지만 얻고, drop(2)는 처음부터 두 번째 엘리먼트까지 버리고 나머지를 버린다는 의미이다.
val list = List(1,2,3)
println(list.drop(1))
println(list.drop(2))
결과는 다음과 같다.
List(2, 3)
List(3)
리스트의 splitAt 메소드는 다음과 같다.
val list = List(1,2,3)
println(list.splitAt(1))
println(list.splitAt(2))
결과는 다음과 같다.
(List(1),List(2, 3))
(List(1, 2),List(3))
스칼라는 각 엘리먼트 요소에 index로 접근할 수 있다.
val list = List(1,2,3)
println(list(0))
println(list(1))
println(list(2))
println()
println(list.apply(0))
println(list.apply(1))
println(list.apply(2))
결과는 다음과 같다.
1
2
3
1
2
3
def apply(n: Int): A = {
val rest = drop(n)
if (n < 0 || rest.isEmpty) throw new IndexOutOfBoundsException("" + n)
rest.head
}
val list = List("s", "a", "m", "u", "e", "l")
println(list.mkString(":"))
val list = List("s", "a", "m", "u", "e", "l")
println(list.toArray mkString " ")
val list = List("s", "a", "m", "u", "e", "l")
val emptyList = new Array[String](7)
list.copyToArray(emptyList, 0)
println(emptyList mkString " ")
val list = List("s", "a", "m", "u", "e", "l")
println(list.map(_ + "X"))
println(list.flatMap(_ + "X"))
val list = List("s", "a", "m", "u", "e", "l")
println(list.filter(_ == "s"))
println(list.find(_ == "s"))
println(list.filter(_ == "z"))
println(list.find(_ == "z"))
val list = List(0,1,2,3,4,0)
println(list.partition(_ > 3))
def partition(p: A => Boolean): (Repr, Repr) = {
val l, r = newBuilder
for (x <- this) (if (p(x)) l else r) += x
(l.result, r.result)
}
@inline final override def takeWhile(p: A => Boolean): List[A] = {
val b = new ListBuffer[A]
var these = this
while (!these.isEmpty && p(these.head)) {
b += these.head
these = these.tail
}
b.toList
}
val list = List(0,1,2,3,4,5,-1,0)
println(list.takeWhile(_ < 4))
println(list.takeWhile(_ > -1))
println(list.takeWhile(_ > 3))
예상대로 되었는지 결과를 살펴본다.
List(0, 1, 2, 3)
List(0, 1, 2, 3, 4, 5)
List()
다음은 takeWhile의 반대 메소드인 dropWhile이다. 결과를 살펴보면, 상반된 결과이지만, 구현이 조금 다르다.
dropWhile의 메소드 원형은 다음과 같다. 내부 메소드와 재귀 메소드를 적절히 사용했다.
@inline final override def dropWhile(p: A => Boolean): List[A] = {
@tailrec
def loop(xs: List[A]): List[A] =
if (xs.isEmpty || !p(xs.head)) xs
else loop(xs.tail)
loop(this)
}
dropWhile 예시는 다음과 같다.
val list = List(0,1,2,3,4,5,-1,0)
println(list.dropWhile(_ < 4))
println(list.dropWhile(_ > -1))
println(list.dropWhile(_ > 3))
결과는 다음과 같다.
List(4, 5, -1, 0)
List(-1, 0)
List(0, 1, 2, 3, 4, 5, -1, 0)
span 메소드는 takeWhile과 dropWhile 두 메소드를 하나도 합쳐 튜플로 리턴한다.
val list = List(0,1,2,3,4,5,-1,0)
println(list.span(_ < 4))
결과는 다음과 같다.
(List(0, 1, 2, 3),List(4, 5, -1, 0))
구현은 다음과 같다.
@inline final override def span(p: A => Boolean): (List[A], List[A]) = {
val b = new ListBuffer[A]
var these = this
while (!these.isEmpty && p(these.head)) {
b += these.head
these = these.tail
}
(b.toList, these)
}
리스트의 forall 메소드와 exists 메소드의 예시이다.
forall 메소드는 리스트의 모든 엘리먼트가 참일 때만 true를 리턴하고, exists 메소드는 하나라도 참이면 true를 리턴한다.
val list = List(0,1,2,3,4,5,-1,0)
println(list.forall(_ > -100))
println(list.exists(_ == 0))
결과는 다음과 같다.
true
true
foldLeft와 foldRight는 우선 순위 연산을 지원하는 메소드이다.
val list = List(1,2,3)
println(list.foldLeft(1)(_ * _))
// ((1 * 1) * 2) * 3 = 6
println(list.foldLeft(2)(_ * _))
// ((2 * 1) * 2) * 3 = 12
println(list.foldRight(1)(_ * _))
// 1 * (2 * (3 * 1)) = 6
println(list.foldRight(2)(_ * _))
// 1 * (2 * (3 * 2)) = 12
결과는 다음과 같다.
6
12
6
12
리스트의 sortWith 메소드는 소팅을 지원한다. 다음 예시는 오른차순, 내림차순을 출력한다.
val list = List(1,2,3,-1,0)
println(list.sortWith(_ < _))
println(list.sortWith(_ > _))
결과는 다음과 같다.
List(-1, 0, 1, 2, 3)
List(3, 2, 1, 0, -1)
리스트의 팩토리 메소드이다.
http://www.scala-lang.org/docu/files/collections-api/collections_45.html
List.empty 예시이다.
println(List.empty)
결과는 List()이다.
List.range 예시이다.
println(List.range(1,5))
println(List.range(1,5,1))
println(List.range(1,6,2))
결과는 다음과 같다. 매개변수는 (start, end, step)을 의미한다.
List(1, 2, 3, 4)
List(1, 2, 3, 4)
List(1, 3, 5)
List.concat 예시이다.
println(List.concat(List('s'), List('a'), List('m')))
결과는 다음과 같다.
List.fill 예시이다.
println(List.fill(2)("samuel"))
예시는 다음과 같다.
List.tabulate 예시이다.
println(List.tabulate(2)(a => a + 1))
결과는 다음과 같다.
List(1, 2)
List.tabulate 메소드로 List(samuel, samuel)를 출력할 수도 있다.
println(List.tabulate(2)(_ => "samuel"))
'scala' 카테고리의 다른 글
[scala] class 예시 2 - 암시적 변환(implicit conversion - implicit converter/implicit class/implicit parameter) (0) | 2016.09.21 |
---|---|
[scala] class 예시 1 - 일반 클래스, 싱글톤 클래스(singleton class), 케이스 클래스(case class), main메소드/App 상속 클래스, 합성 타입(Compound), 제네릭(generic) 클래스 (0) | 2016.09.20 |
[scala] List 정의와 예시 (0) | 2016.09.13 |
[scala] Array 예시 (0) | 2016.09.12 |
[scala] zip, unzip 예시 (0) | 2016.09.12 |