繁体   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