程式扎記: [Scala 文章收集] Scala for/yield examples

標籤

2016年8月11日 星期四

[Scala 文章收集] Scala for/yield examples

Source From Here
Preface
For each iteration of your for loop, yield generates a value which will be remembered. It's like the for loop has a buffer you can't see, and for each iteration of your for loop, another item is added to that buffer. When your forloop finishes running, it will return this collection of all the yielded values. The type of the collection that is returned is the same type that you were iterating over, so a Map yields a Map, a List yields a List, and so on.

Also, note that the initial collection is not changed; the for/yield construct creates a new collection according to the algorithm you specify.


Basic for loop examples
Given that background information, let's take a look at a few for/yield examples. First, let's just yield a collection that is identical to the collection we are looping over:
scala> for(i <- 1="" 5="" font="" i="" to="" yield="">
res0: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 2, 3, 4, 5)

Nothing too exciting there, but it's a start. Next, let's double every element in our initial collection:
scala> for(i <- 1="" 5="" font="" i="" to="" yield="">
res1: scala.collection.immutable.IndexedSeq[Int] = Vector(2, 4, 6, 8, 10)

Here's what the modulus operator does in a for/yield loop:
scala> for(i <- 1="" 2="" 5="" font="" i="" to="" yield="">
res2: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 0, 1, 0, 1)

for loop yield examples over a Scala Array
I mentioned in my description that the for loop yield construct returns a collection that is the same as the collection it is given. To demonstrate this, let's look at the same examples with a Scala Array. Note the type of the collection that is yielded, and compare it to the previous examples:
scala> val a = Array(1, 2, 3, 4, 5)
a: Array[Int] = Array(1, 2, 3, 4, 5)

scala> for(e <- a="" e="" font="" yield="">
res0: Array[Int] = Array(1, 2, 3, 4, 5)

scala> for(e <- 2="" a="" e="" font="" yield="">
res1: Array[Int] = Array(2, 4, 6, 8, 10)

scala> for(e <- 2="" a="" e="" font="" yield="">
res2: Array[Int] = Array(1, 0, 1, 0, 1)

As you can see, in these examples an Array[Int] was yielded, while in the earlier examples an IndexedSeq[Int] was returned.

for loop, yield, and guards (for loop 'if' conditions)
If you're familiar with the Scala for comprehension syntax, you know that you can add 'if' statements to your for loop construct. Tests like these are often referred to as "guards", and you can combine them with the yield syntax, as shown here:
scala> (1 to 10).toList.toArray
res8: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> val a = (1 to 10).toList.toArray
a: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> for(e <- 2="=0)" a="" e="" font="" if="" yield="">
res9: Array[Int] = Array(2, 4, 6, 8, 10)

A real-world example
I don’t know if this will make sense out of context, but if you’d like to see a real-world use of a for/yield loop, here you go:
  1. def getQueryAsSeq(query: String): Seq[MiniTweet] = {  
  2.     val queryResults = getTwitterInstance.search(new Query(query))  
  3.     val tweets = queryResults.getTweets  // java.util.List[Status]  
  4.     for (status <- listtweet="" nbsp="" span="" status.getcreatedat.tostring="" status.gettext="" status.getuser.tostring="" tweets="" yield="">
  5. }  
This code uses the JavaConversions package to convert the java.util.List[Status] I get back from Twitter4J into a Seq[MiniTweet]. The loop actually returns a Buffer[ListTweet], which is a Seq[ListTweet]. A MiniTweet is just a small version of a Twitter tweet, with the three fields shown.

Summary
If you're familiar with Scala's for loop construct, you know that there's also much more work that can be performed in the first set of parentheses. You can add "if" statements and other statements there, such as this example from the book Programming in Scala:
  1. def scalaFiles =   
  2.   for {  
  3.     file <- fileshere="" nbsp="" span="">
  4.     if file.getName.endsWith(".scala")  
  5.   } yield file  
I'll try to share more complicated examples like this in the future, but for today I wanted to share some simple for/yield examples, something like "An introduction to the Scala yield keyword." As a quick summary of the yield keyword:
- For each iteration of your for loop, yield generates a value which is remembered by the for loop (behind the scenes, like a buffer).
- When your for loop finishes running, it returns a collection of all these yielded values.
- The type of the collection that is returned is the same type that you were iterating over.


沒有留言:

張貼留言

網誌存檔