[英]F# - Code improvement
我是F#的新手,我想出了一個相當簡單的問題的解決方案,即給定一串數字,我需要將每個數字乘以2,然后得到這些數字的總和。 例如,字符串“ 123456”應等於24
這就是我想出的
let input = "123456"
|> Seq.map (string >> int)
|> Seq.map (fun(x) -> x * 2)
|> Seq.map (int >> string)
|> String.concat String.Empty
|> Seq.map (string >> int)
|> Seq.sum
我的問題是,我可以做一些實質性的改變來使我的解決方案更簡潔,更有效嗎? 任何幫助將不勝感激
您可以通過應用一些屬性來壓縮代碼。
fun x -> x * 2
是
fun x -> (*) x 2
(運算符作為函數)
fun x -> (*) 2 x
(可交換)
(*) 2
(減少eta)
map
組成與要映射的函數的組成相同,您的前三個map可以寫為:
Seq.map (string >> int >> (*) 2 >> string)
map
,然后collect
concat
map
,然后sum
是sumBy
因此,您的代碼可能是:
"123456"
|> String.collect (string >> int >> (*) 2 >> string)
|> Seq.sumBy (string >> int)
我知道這可能是一個玩具示例,但我認為以可讀的方式編寫它實際上非常困難。 在我真正了解發生了什么之前,我必須逐行運行您的代碼!
您絕對可以使用無點樣式將其壓縮為很短的表達式(如Gustavo的答案所示),但是我可能不會走得那么遠-因為您以后可能需要閱讀和理解代碼!
另一種方法是使用序列表達式並編寫如下內容:
[ for c in "123456" do
// Get the number, multiply it & yield its characters
let number = int (string c)
yield! string (number * 2) ]
// Sum the numbers (converting char to int via a string)
|> Seq.sumBy (string >> int)
這比您的原始版本短一些,但是(我認為)仍然可以理解。
就效率而言,與其直接將字符串中的每個字符轉換成字符串,不如將其轉換為整數。
|> Seq.map (string >> int)
我將字符直接轉換為數字:
|> Seq.map (Char.GetNumericValue >> int)
這樣可以減少收集的垃圾,盡管我尚未對其進行基准測試,但我希望它會更快。
就像Tomas所說的那樣,我在原始帖子中沒有考慮過數字的要求。 所以這是我的更正版本:
"123456"
|> Seq.map (string >> int) // Convert to int sequence
|> Seq.collect(fun x -> string(x*2)) // Perform multiplication,
// convert to string and collect the digits as chars
|> Seq.sumBy (string >> int) // Convert the chars to string and than to integer
// to sum them correctly
古斯塔沃發布的內容大致相同。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.