Функциональный стиль для этого кода Scala
Мой друг изучает Scala и пишет этот простой код для отслеживания самой длинной строки в файле:
val longest = (filename:String) => {
val is = new FileInputStream(filename)
val buf = new Array[Byte](1024)
var longest=0 //keep track of the longest line
var lastPos=0
var read=0
try {
read = is.read(buf)
while (read > 0) {
for (i<-0 until read) {
if (buf(i) == '\n') {
val size=i-lastPos-1
lastPos=i
if (size>longest) {
longest=size
}
}
}
lastPos-=buf.length
read=is.read(buf)
}
} finally {
is.close()
}
longest
}
Я новичок в Scala, но я уверен, что в этом коде есть много возможностей для flatMaps и других функций.
Может ли кто-нибудь опубликовать функциональную версию этого?
Ответы
Ответ 1
Альтернативная реализация:
def longest(filename: String) =
Source.fromFile(filename).getLines.map(_.size).max
Краткое объяснение:
-
getLines
возвращает итератор строк в файле;
-
map(_.size)
, эквивалентный map(line => line.size)
, возвращает новый итератор длины строк
-
max
возвращает наибольшую длину строки.
Ответ 2
val longest = (filename: String) =>
io.Source.fromFile(filename).getLines.maxBy(_.length).length
Ответ 3
Да, этот код мучительно необходим. В Scala грубый эквивалент был бы (!):
def longest(fileName: String) =
Source.fromFile(fileName).getLines().max(Ordering.fromLessThan[String](_.size < _.size)).size
Угадайте, не помешало бы дать какое-то объяснение:
def longest(fileName: String) = Source.
fromFile(fileName). //file contents abstraction
getLines(). //iterator over lines
max( //find the max element in iterated elements
Ordering.fromLessThan[String](_.size < _.size) //however, use custom comparator by line size
).size //max() will return the line, we want the line length
Конечно TMTOWTDI в Scala.