Расширить предыдущий ответ ...
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
}