Reputation: 1127
How does the behavior of the for-loop change when a Set
instance is given instead of a List
instance?
Fiddle: http://scalafiddle.net/console/67ed94744426295f96268f4ac1881b46
Code:
case class Book(title: String, authors: List[String]) {}
val books = List(
Book("Book 1", List("Author 1", "Author 2")),
Book("Book 2", List("Author 2")),
Book("Book 3", List("Author 3")),
Book("Book 4", List("Author 4"))
)
def authorsWithMultipleBooks(books: Iterable[Book]) =
for {
b1 <- books
b2 <- books
if b1 != b2
a1 <- b1.authors
a2 <- b2.authors
if a1 == a2
} yield a1
println(authorsWithMultipleBooks(books))
// Output: List(Author 2, Author 2)
println(authorsWithMultipleBooks(books.toSet))
// Output: Set(Author 2)
Upvotes: 0
Views: 47
Reputation: 108101
In both cases you yield "Author 2"
twice, but since Set
only holds one istance of each element, the second time you yield it it doesn't change the set.
So the for loop doesn't change in its behavior, the only thing acting differently is the insertion in the resulting collection, which - being a set - discards duplicate insertions.
Here's an example to further clarify the idea:
scala> val authors = List("Author 1", "Author 2", "Author 3")
authors: List[String] = List(Author 1, Author 2, Author 3)
scala> for {
| _ <- authors
| } yield "Author 2"
res8: List[String] = List(Author 2, Author 2, Author 2)
scala> val authorsSet = authors.toSet
authorsSet: scala.collection.immutable.Set[String] = Set(Author 1, Author 2, Author 3)
scala> for {
| _ <- authorsSet
| } yield "Author 2"
res10: scala.collection.immutable.Set[String] = Set(Author 2)
Upvotes: 3