Phát biểu Nghiêm làm thế nào để định dạng mã mà, mà không thực hiện bất kỳ thay đổi cấu trúc, tôi muốn làm điều đó như thế này:
Console println (
(
io.Source
fromFile "names.txt"
getLines()
mkString ""
split ","
map (x => x.slice(1, x.length - 1))
sortBy (x => x)
zipWithIndex
)
map (t => (t._2 + 1) * (t._1 map (_.toChar - "A"(0).toChar + 1) sum))
sum
)
Hoặc, có lẽ, để có được xung quanh phương pháp parameterless, tôi muốn làm điều này:
Console println (
io.Source
.fromFile("names.txt")
.getLines
.mkString
.split(",")
.map(x => x.slice(1, x.length - 1))
.sortBy(x => x)
.zipWithIndex
.map(t => (t._2 + 1) * (t._1 map (_.toChar - "A"(0).toChar + 1) sum))
.sum
)
Lưu ý rằng có nhiều không gian cho ý kiến, nhưng, nói chung, những gì đang được thực hiện thường rõ ràng. Những người không quen với nó đôi khi có thể bị mất nửa chừng, không có biến để theo dõi ý nghĩa/loại của giá trị được chuyển đổi .
Bây giờ, một số những điều tôi muốn làm khác đi là:
println (// instead of Console println
Source // put import elsewhere
.fromFile("names.txt")
.mkString // Unless you want to get rid of /n, which is unnecessary here
.split(",")
.map(x => x.slice(1, x.length - 1))
.sorted // instead of sortBy
.zipWithIndex
.map { // use { only for multiple statements and, as in this case, pattern matching
case (c, index) => (index + 1) * (c map (_ - 'A' + 1) sum) // chars are chars
}
.sum
)
Tôi cũng không làm tổng và nhân lên trong các bước tương tự, vì vậy:
.sorted
.map(_ map (_ - 'A' + 1) sum)
.zipWithIndex
.map { case (av, index) => av * (index + 1) }
.sum
Cuối cùng, tôi don' Tôi thích thay đổi kích thước chuỗi, vì vậy tôi có thể sử dụng regex để thay thế. Thêm một chút tái cấu trúc, và đây là điều mà tôi có thể viết:
import scala.io.Source
def names = Source fromFile "names.txt" mkString
def wordExtractor = """"(.*?)"""".r
def words = for {
m <- wordExtractor findAllIn names matchData
} yield m group 1
def alphabeticValue(s: String) = s map (_ - 'A' + 1) sum
def wordsAV = words.toList.sorted map alphabeticValue
def multByIndex(t: (Int, Int)) = t match {
case (av, index) => av * (index + 1)
}
def wordsAVByIndex = wordsAV.zipWithIndex map multByIndex
println(wordsAVByIndex.sum)
EDIT
Bước tiếp theo sẽ là một refactoring đổi tên - chọn tên mà truyền đạt tốt hơn những gì mỗi một phần của mã đang làm. Ken đề xuất tên tốt hơn trong các ý kiến, và tôi thích hợp cho họ cho một biến thể hơn (nó cũng giới thiệu độc đáo bao nhiêu tốt hơn đặt tên cải thiện khả năng đọc).
import scala.io.Source
def rawData = Source fromFile "names.txt" mkString
// I'd rather write "match" than "m" in the next snippet, but
// the former is a keyword in Scala, so "m" has become more
// common in my code than "i". Also, make the return type of
// getWordsOf clear, because iterators can be tricky.
// Returning a list, however, makes a much less cleaner
// definition.
def wordExtractor = """"(.*?)"""".r
def getWordsOf(input: String): Iterator[String] = for {
m <- wordExtractor findAllIn input matchData
} yield m group 1
def wordList = getWordsOf(rawData).toList
// I stole letterPosition from Kevin's solution. There, I said it. :-)
def letterPosition(c: Char) = c.toUpper - 'A' + 1 // .toUpper isn't necessary
def alphabeticValueOfWord(word: String) = word map letterPosition sum
def alphabeticValues = wordList.sorted map alphabeticValueOfWord
// I don't like multAVByIndex, but I haven't decided on a better
// option yet. I'm not very fond of declaring methods that return
// functions either, but I find that better than explicitly handling
// tuples (oh, for the day tuples/arguments are unified!).
def multAVByIndex = (alphabeticValue: Int, index: Int) =>
alphabeticValue * (index + 1)
def scores = alphabeticValues.zipWithIndex map multAVByIndex.tupled
println(scores sum)
Tôi không có đủ kinh nghiệm với Scala để cung cấp cho bạn lời khuyên tốt, nhưng nó có thể hữu ích nếu bạn phá vỡ từng bản đồ thành một dòng khác? Tôi quan tâm để tìm hiểu những gì Scala-ites thực sự phải nói về điều này. –
Một quy tắc rất quan trọng và ngôn ngữ-/mô-thuyết bất khả tri không phải là tạo các dòng dài hơn 80 (hoặc một giá trị hợp lý khác). 190 ký tự chỉ là điên rồ (và nếu bạn đang chơi golf, ít nhất hãy giảm xuống 130 hoặc bạn sẽ không bao giờ đánh bại perl!;)). – delnan
Đồng ý, đó là lý do dài vì lý do sư phạm. Nhưng câu hỏi của tôi là một phần về cách tốt nhất để chia nó thành những phần nhỏ hơn, ngoài việc lựa chọn các ngắt chỉ để tạo ra các dòng <80 ký tự. Tôi không chơi gôn, nhưng tôi đang cố gắng cải thiện lập trình chức năng của mình ... –