Skip to content

Scala:ForComprehensions

About

스칼라 Doc 에서는 이렇게 말합니다.

파이썬, 루비등에 있는 yield 처럼 스칼라도 yield 를 가지고 있지만 좀 다릅니다. 스칼라의 yield 는 for comprehensions 의 일부분으로 사용되며, 다른 언어의 list-comprehensions 의 일반화 입니다. 스칼라의 "for comprehensions" 는 하스켈의 "do" 와 동등하며 멀티플모나딕 연산을 위한 사용편의 정도일 뿐입니다.

Examples

그냥 간단한 for문:

for(i <- 1 to 3) {
  println(i)
}

그냥 간단한 for문:

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)

조건 추가. (결과는 Boolean 으로 적용)

val a =  for(i <- 1 to 3) yield i > 2;
println(a) // Vector(false, false, true)

yieldfor 조건문에 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 10 ; if i > 5 ; if i % 2 == 0 ) yield i
println(a) // Vector(6, 8, 10)

List를 사용할 수 있고, { }를 이용하여 확장할 수 있다:

val list = List(1, 2, 3)
val a = for {
  element <- list
} yield {
  element
}
println(a) // List(1, 2, 3)

yield 내용을 { }을 이용하여 확장:

val list = List(1, 2, 3)
val a = for {
  i <- list
} yield {
  i > 2
}
println(a) // List(false, false, true)

if를 사용한 필터링도 가능:

val list = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val a = for {
  i <- list
  if i > 5
  if i % 2 == 0
} yield {
  i
}
println(a) // List(6, 8, 10)

for문에 여러 개의 List 사용:

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 scores = List(100, 80, 90)
val zipped = names.zip(scores)
val example = for ((name, score) <- zipped) yield name + "-" + score
println(example) // 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)

No yield example

yield 없이 사용 가능:

for (i <- Iterator.range(0, 20);
    j <- Iterator.range(i + 1, 20) if i + j == 32)
  println("(" + i + ", " + j + ")")

명령형 언어의 일반적인 루프와 비슷하다. 결과는:

(13, 19)
(14, 18)
(15, 17)

See also

Favorite site