Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

scala loop through a linkedlist

Tags:

scala

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

like image 778
NullPointer0x00 Avatar asked Dec 02 '25 08:12

NullPointer0x00


2 Answers

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)
like image 178
Synesso Avatar answered Dec 04 '25 00:12

Synesso


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
}
like image 41
Kevin Wright Avatar answered Dec 04 '25 00:12

Kevin Wright



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!