for..yield는 for comprehension (sequence comprehension)이라 불린다.
for.. yield 는 상황에 따라 foreach, flatmap, filter, map으로 translate 할 수 있는 문법 설탕(https://en.wikipedia.org/wiki/Syntactic_sugar)이다.
개발자가 개발하기 쉽도록 (또는 보기 편하도록) 설계된 문법이다.
좀 더 재미있는 내용을 살펴보고 싶다면, http://stackoverflow.com/questions/1052476/what-is-scalas-yield를 참조하면 즐거울 것 같다.
예시 시작
그냥 간단한 for문이다.
for(i <- 1 to 3) {
println(i)
}
결과
1
2
3
REPL에서 yield를 사용하면 결과가 Vector 타입의 인스턴스로 리턴한다.
scala> for(i <- 1 to 3) yield i
res2: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 2, 3)
val a = for(i <- 1 to 3) yield i;
println(a)
결과
Vector(1, 2, 3)
yield 값에 곱셈을 추가해본다.
val a = for(i <- 1 to 3) yield i * 100;
println(a)
결과
Vector(100, 200, 300)
yield 뒤에 조건문을 두어 실행한다.
val a = for(i <- 1 to 3) yield i > 2;
println(a)
결과
Vector(false, false, true)
yield 앞 for 조건문에 if 문을 둔다. 마치 filter의 효과를 둔다.
val a = for( i <- 1 to 3 ; if i == 1 ) yield i
println(a)
결과
Vector(1)
if 문을 여러 개 두어 필터링을 할 수 있다.
val a = for( i <- 1 to 3 ; if i == 1 ; if i == 2 ) yield i
println(a)
List를 사용할 수 있고, { }를 이용하여 확장할 수 있다.
val list = List(1, 2, 3)
val a = for {
element <- list
} yield {
element
}
println(a)
결과
List(1, 2, 3)
앞에서 테스트한 내용을 {}을 이용하여 확장하였다. 결과는 동일하다.
A 코드
val a = for(i <- 1 to 3) yield i > 2;
println(a)
B 코드
val list = List(1, 2, 3)
val a = for {
i <- list
} yield {
i > 2
}
println(a)
결과
List(false, false, true)
for 문에 List 2개를 넣었다. loop 두 개의 효과가 발생한다.
val list = List(1, 2, 3)
val list2 = List(10, 20)
val a = for {
i <- list
j <- list2
} yield {
i
}
println(a)
결과
List(1, 1, 2, 2, 3, 3)
val list = List(1, 2, 3)
val list2 = List(10, 20)
val a = for {
i <- list
j <- list2
} yield {
i * j
}
println(a)
결과
List(10, 20, 20, 40, 30, 60)
val list = List(1, 2, 3)
val list2 = List(10, 20)
val list3 = List(1, 2)
val a = for {
i <- list
j <- list2
z <- list3
} yield {
i + j + z
}
println(a)
결과
List(12, 13, 22, 23, 13, 14, 23, 24, 14, 15, 24, 25)
튜플을 만들 수도 있다.
val list = List(1, 2, 3)
val list2 = List("x", "y")
val a = for {
i <- list
j <- list2
} yield {
(i, j)
}
println(a)
결과
List((1,x), (1,y), (2,x), (2,y), (3,x), (3,y))
두 리스트의 엘리먼트를 하나로 합쳐주는 zip 함수를 사용하여 단일 리스트로 만든 후, for.. yield를 사용할 수 있다.
val names = List("Jax", "Peter", "Tony")
val score = List(100, 80, 90)
val zipped = names.zip(score);
val example = for ((name, score) <- zipped) yield name + "-" + score
println(example);
결과
List(Jax-100, Peter-80, Tony-90)
zipped는 List((Jax,100), (Peter,80), (Tony,90)) 이다.
두 리스트의 중복 요소를 찾는 경우에도 사용할 수 있다.
val list1 = List(1, 2, 3)
val list2 = List(7, 9, 1)
val result = for (e1 <- list1 ; e2 <- list2 if e1 == e2) yield e1
print(result)
결과
List(1)
'scala' 카테고리의 다른 글
[scala] Stream 객체를 써서 List의 요소를 반복하기 (0) | 2016.09.07 |
---|---|
[scala] package object 예제 (0) | 2016.09.07 |
[scala 2.11.8] 간단한 변수 스코프 테스트시 유의사항 (0) | 2016.04.04 |
[scala] jad로 디컴파일(decompile)하기, javap, scalac 사용하기 (0) | 2016.03.26 |
[scala] 암시적 타입 변환(implicit type conversion) 예시 (0) | 2016.03.25 |