Scala цикл через связанный список - PullRequest
2 голосов
/ 04 ноября 2010

В scala, что является хорошим способом перебрать связанный список (scala.collection.mutable.LinkedList) объектов?Например, я хочу, чтобы цикл «for» проходил через каждый объект в связанном списке и обрабатывал его.

Ответы [ 2 ]

11 голосов
/ 04 ноября 2010

С 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

или, если обработка каждого объекта возвращает новое значение, используйте карту:

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

Некоторые люди предпочитают для понимания вместо foreach и map.Они выглядят так:

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)
9 голосов
/ 04 ноября 2010

Расширить предыдущий ответ ... for, foreach и map - все функции высшего порядка - все они могут принимать функцию в качестве аргумента, поэтому начнем здесь:

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

У вас есть несколько способов сделать код более декларативным по своей природе и в то же время более чистым.

Во-первых, вам не нужно использовать имя - i - для каждого члена коллекции вы можете использовать _ вместо заполнителя:

list.foreach(println(_ * 2))

Вы также можете разделить логику на отдельный метод и продолжать использовать синтаксис заполнителя:

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

Еще чище, просто передать необработанную функцию без указания параметров ( смотри, нет заполнителей! )

list.foreach(printTimesTwo)

И чтобы прийти к логическому выводу, это можно сделать еще чище, используя синтаксис infix . Который я показываю здесь, работая со стандартным библиотечным методом. Примечание: вы даже можете использовать метод, импортированный из библиотеки Java, если хотите :

list foreach println

Это мышление распространяется на анонимные функции и частично примененные функции , а также на операцию отображения:

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

Фор-понимания не очень полезны при работе на этом уровне, они просто добавляют шаблон. Но они работают сами по себе при работе с более глубокими вложенными структурами:

//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

Мне не нужно было ключевое слово yield, так как ничего не возвращается. Но если бы я хотел получить список строк (не вложенных):

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

С большим количеством генераторов вы захотите разбить их на несколько строк:

for {
  listOfGrids <- someMasterCollection
  grid <- listOfGrids
  line <- grid
  cell <- line
} yield {
  cell.toString
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...