开发者

scala loop through a linkedlist

In scala, what is a good way to loop through a linked list(scala.collection.mut开发者_Python百科able.LinkedList) of objects? For example, I want to have 'for' loop traverse through each object on the linked list and process it.


With foreach:

Welcome to Scala version 2.8.0.final (Java HotSpot(TM) Client VM, Java 1.6.0_21).
Type in expressions to have them evaluated.
Type :help for more information.

scala> val ll = scala.collection.mutable.LinkedList[Int](1,2,3)
ll: scala.collection.mutable.LinkedList[Int] = LinkedList(1, 2, 3)

scala> ll.foreach(i => println(i * 2))
2
4
6

or, if your processing of each object returns a new value, use map:

scala> ll.map(_ * 2)                  
res3: scala.collection.mutable.LinkedList[Int] = LinkedList(2, 4, 6)

Some people prefer for comprehensions instead of foreach and map. They look like this:

scala> for (i <- ll) println(i)
1
2
3

scala> for (i <- ll) yield i * 2
res5: scala.collection.mutable.LinkedList[Int] = LinkedList(2, 4, 6)


To expand on the previous answer... for, foreach and map are all higher-order functions - they can all take a function as an argument, so starting here:

val list = List(1,2,3)
list.foreach(i => println(i * 2))

You have a number of ways that you can make the code more declarative in nature, and cleaner at the same time.

First, you don't really need to use the name - i - for each member of the collection, you can use _ as a placeholder instead:

list.foreach(println(_ * 2))

You can also separate the logic out into a distinct method, and continue to use placeholder syntax:

def printTimesTwo(i:Int) = println(i * 2)
list.foreach(printTimesTwo(_))

Even cleaner, just pass the raw function without specifying parameters (look ma, no placeholders!)

list.foreach(printTimesTwo)

And to take it to a logical conclusion, this can be made cleaner still by using infix syntax. Which I show here working with a standard library method. Note: you could even use a method imported from a java library, if you wanted:

list foreach println

This thinking extends to anonymous functions and partially-applied functions and also to the map operation:

// "2 *" creates an anonymous function that will double its one-and-only argument
list map { 2 * }

For-comprehensions aren't really very useful when working at this level, they just add boilerplate. But they do come into their own when working with deeper nested structures:

//a list of lists, print out all the numbers
val grid = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9))
grid foreach { _ foreach println } //hmm, could get confusing
for(line <- grid; cell <- line) println(cell) //that's clearer

I didn't need the yield keyword there, as nothing is being returned. But if I wanted to get back a list of Strings (un-nested):

for(line <- grid; cell <- line) yield { cell.toString }

With lots of generators, you'll want to split them over multiple lines:

for {
  listOfGrids <- someMasterCollection
  grid <- listOfGrids
  line <- grid
  cell <- line
} yield {
  cell.toString
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜