簡體   English   中英

F#-代碼改進

[英]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 ,然后sumsumBy

因此,您的代碼可能是:

"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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM