Skip to content

Commit ee79010

Browse files
authored
Merge pull request #28 from cankill/master
For loops in Scala
2 parents e074f97 + 0b3839d commit ee79010

File tree

2 files changed

+209
-0
lines changed

2 files changed

+209
-0
lines changed
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package com.baeldung.scala.forcomprehension
2+
3+
trait ForLoop {
4+
// We are defining a println in a separate function in order to be able to test our iterations
5+
def sideEffectFunction(arg: Any) = println(arg)
6+
7+
// Iterating an exclusive Range
8+
def iterateRangeTo (rangeTo: Range): Unit = {
9+
for (num <- rangeTo) {
10+
sideEffectFunction(num)
11+
}
12+
}
13+
14+
// Iterating an inclusive Range
15+
def iterateRangeUntil (rangeUntil: Range): Unit = {
16+
for (num <- rangeUntil) {
17+
sideEffectFunction(num)
18+
}
19+
}
20+
21+
// Iterating the Ranges as multiple generators
22+
def multipleGenerators (rangeTo: Range, rangeUntil: Range): Unit = {
23+
for {
24+
i <- rangeTo
25+
j <- rangeUntil
26+
} {
27+
sideEffectFunction(s"$i, $j")
28+
}
29+
}
30+
31+
// Iterating a Sequence of Strings
32+
def iterateCollection (colors: Seq[String]): Unit = {
33+
for (color <- colors) {
34+
sideEffectFunction(color)
35+
}
36+
}
37+
38+
// Iterating a Sequences of Strings, with multiple generators
39+
def iterateCollectionWithMultipleGenerators (colors: Seq[String]): Unit = {
40+
for (c1 <- colors; c2 <- colors; c3 <- colors) {
41+
sideEffectFunction(s"$c1$c2$c3 ")
42+
}
43+
}
44+
45+
// Iterating a Sequences of Strings, with multiple generators and guards
46+
def iterateCollectionsWithGuards(colors: Seq[String]): Unit = {
47+
for {
48+
c1 <- colors
49+
c2 <- colors
50+
if c2 != c1
51+
c3 <- colors
52+
if c3 != c2 && c3 != c1
53+
} {
54+
sideEffectFunction(s"$c1$c2$c3 ")
55+
}
56+
}
57+
58+
// Iterating a Map of String to Strings
59+
def iterateMap (map: Map[String, String]): Unit = {
60+
for ((key,value) <- map) {
61+
sideEffectFunction(s"""$key is for $value""")
62+
}
63+
}
64+
65+
// Iterating a Map of String to List of Strings
66+
def iterateMapMultipleGenerators (deck: Map[String, List[String]]): Unit = {
67+
for {
68+
(suit, cards) <- deck
69+
card <- cards
70+
} {
71+
sideEffectFunction(s"""$card of $suit""")
72+
}
73+
}
74+
75+
// Pure List iteration
76+
def pureIteration (numbers: List[Int]): List[String] = {
77+
for (number <- numbers) yield {
78+
s"""$number + $number = ${number + number}"""
79+
}
80+
}
81+
82+
// Pure multiple Optional with for-comprehension
83+
def forComprehensionWithOptionals (someIntValue: Option[Int], someStringValue: Option[String]): Option[String] = {
84+
for {
85+
intValue <- someIntValue
86+
stringValue <- someStringValue
87+
} yield {
88+
s"""$intValue is $stringValue"""
89+
}
90+
}
91+
92+
// Pure multiple Optional with map/flatMap
93+
def mapOptionals (someIntValue: Option[Int], someStringValue: Option[String]): Option[String] = {
94+
someIntValue.flatMap(intValue => someStringValue.map(stringValue => s"""$intValue is $stringValue"""))
95+
}
96+
}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package com.baeldung.scala.forcomprehension
2+
3+
import org.junit.Assert.assertEquals
4+
import org.junit.{Before, Test}
5+
6+
class ForLoopImplementation extends ForLoop {
7+
var sideEffectResult: Seq[Any] = Nil
8+
override def sideEffectFunction (arg: Any): Unit = {
9+
sideEffectResult = sideEffectResult :+ arg
10+
}
11+
12+
def clean(): Unit = {
13+
sideEffectResult = Nil;
14+
}
15+
}
16+
17+
class ForLoopUnitTest {
18+
val forLoopTest = new ForLoopImplementation
19+
val rangeTo: Range = 1 to 3
20+
val rangeUntil: Range = 1 until 3
21+
val colors = Seq("R", "G", "B")
22+
val map = Map("R" -> "Red", "G" -> "Green", "B" -> "Blue")
23+
val deck = Map("" -> List("A", "K", "Q"),
24+
"" -> List("J", "10"),
25+
"" -> List("9", "8", "7"),
26+
"" -> List("A", "K", "J", "6"))
27+
val numbers = List(1, 2, 3)
28+
val someIntValue: Option[Int] = Some(10)
29+
val someStringValue: Option[String] = Some("Ten")
30+
31+
@Before
32+
def init(): Unit = {
33+
forLoopTest.clean()
34+
}
35+
36+
//givenXXX_whenYYY_thenZZZ or whenXXX_thenYYY
37+
38+
@Test
39+
def givenInclusiveRange_whenForLoop_thenIterateOverEachElement (): Unit = {
40+
forLoopTest.iterateRangeTo(rangeTo)
41+
val expected = Seq(1, 2, 3)
42+
assertEquals(expected, forLoopTest.sideEffectResult)
43+
}
44+
45+
@Test
46+
def givenExclusiveRange_whenForLoop_thenIterateOverEachElement (): Unit = {
47+
forLoopTest.iterateRangeUntil(rangeUntil)
48+
val expected = Seq(1, 2)
49+
assertEquals(expected, forLoopTest.sideEffectResult)
50+
}
51+
52+
@Test
53+
def givenExclusiveAndInclusiveRange_whenForLoopWithMltipleGenerators_thenCartesianProduct (): Unit = {
54+
forLoopTest.multipleGenerators(rangeTo, rangeUntil)
55+
val expected = Seq("1, 1", "1, 2", "2, 1", "2, 2", "3, 1", "3, 2")
56+
assertEquals(expected, forLoopTest.sideEffectResult)
57+
}
58+
59+
@Test
60+
def givenCollection_whenForLoop_thenIterateOverEachElement (): Unit = {
61+
forLoopTest.iterateCollection(colors)
62+
val expected = Seq("R", "G", "B")
63+
assertEquals(expected, forLoopTest.sideEffectResult)
64+
}
65+
66+
@Test
67+
def givenCollection_whenForLoopWithMltipleGenerators_thenAllPossibleCombinations (): Unit = {
68+
forLoopTest.iterateCollectionWithMultipleGenerators(colors)
69+
val expected = List("RRR ", "RRG ", "RRB ", "RGR ", "RGG ", "RGB ", "RBR ", "RBG ", "RBB ",
70+
"GRR ", "GRG ", "GRB ", "GGR ", "GGG ", "GGB ", "GBR ", "GBG ", "GBB ",
71+
"BRR ", "BRG ", "BRB ", "BGR ", "BGG ", "BGB ", "BBR ", "BBG ", "BBB ")
72+
assertEquals(expected, forLoopTest.sideEffectResult)
73+
}
74+
75+
@Test
76+
def givenCollection_whenForLoopWithMltipleGeneratorsAndGuards_thenUniqueLettersCombinations (): Unit = {
77+
forLoopTest.iterateCollectionsWithGuards(colors)
78+
val expected = List("RGB ", "RBG ", "GRB ", "GBR ", "BRG ", "BGR ")
79+
assertEquals(expected, forLoopTest.sideEffectResult)
80+
}
81+
82+
@Test
83+
def givenMap_whenForLoop_thenCollectionOfStrings (): Unit = {
84+
forLoopTest.iterateMap(map)
85+
val expected = List("R is for Red", "G is for Green", "B is for Blue")
86+
assertEquals(expected, forLoopTest.sideEffectResult)
87+
}
88+
89+
@Test
90+
def givenMap_whenForLoopWithMltipleGenerators_thenAllCombinationsOfKeyAndValueList (): Unit = {
91+
forLoopTest.iterateMapMultipleGenerators(deck)
92+
val expected = List("A of ♣", "K of ♣", "Q of ♣", "J of ♦", "10 of ♦", "9 of ♥", "8 of ♥", "7 of ♥", "A of ♠", "K of ♠", "J of ♠", "6 of ♠")
93+
assertEquals(expected, forLoopTest.sideEffectResult)
94+
}
95+
96+
@Test
97+
def givenCollection_whenForComprehension_thenReturnedCollectionOfStrings (): Unit = {
98+
val result = forLoopTest.pureIteration(numbers)
99+
val expected = List("1 + 1 = 2", "2 + 2 = 4", "3 + 3 = 6")
100+
assertEquals(expected, result)
101+
}
102+
103+
@Test
104+
def givenOptionals_whenForComprehensionOrMap_thenReturnedOptional (): Unit = {
105+
106+
val resultFor = forLoopTest.forComprehensionWithOptionals(someIntValue, someStringValue)
107+
val resultMap = forLoopTest.mapOptionals(someIntValue, someStringValue)
108+
val expected = Some("10 is Ten")
109+
assertEquals(expected, resultFor)
110+
assertEquals(expected, resultMap)
111+
assertEquals(resultFor, resultMap)
112+
}
113+
}

0 commit comments

Comments
 (0)