Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F#-代码改进_F# - Fatal编程技术网

F#-代码改进

F#-代码改进,f#,F#,我对F#不熟悉,我想出了一个相当简单的问题的解决方案,就是给定一个数字串,我需要将每个数字乘以2,然后得到这些数字的总和。例如,字符串“123456”应等于24 这是我能想到的 let input = "123456" |> Seq.map (string >> int) |> Seq.map (fun(x) -> x * 2) |> Seq.map (int >> string) |

我对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

我的问题是,我能做些什么实质性的改变,使我的解决方案更简洁、更有效吗?任何帮助都将不胜感激

您可以通过应用一些属性来压缩代码

funx->x*2

fun x->(*)x 2
(运算符作为函数)

funx->(*)2x
(可交换)

(*)2
(eta降低)

map
组合与要映射的函数的组合相同,前3个映射可以写成:

Seq.map (string >> int >> (*) 2 >> string)
map
然后
concat
collect

map
然后
sum
sumBy

因此,您的代码可以是:

"123456"
    |> String.collect (string >> int >> (*) 2 >> string)
    |> Seq.sumBy (string >> int)

您可以通过应用一些属性来压缩代码

funx->x*2

fun x->(*)x 2
(运算符作为函数)

funx->(*)2x
(可交换)

(*)2
(eta降低)

map
组合与要映射的函数的组合相同,前3个映射可以写成:

Seq.map (string >> int >> (*) 2 >> string)
map
然后
concat
collect

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)

这比您的原始版本短了一点,但(我认为)仍然可以理解。

我理解这可能是一个玩具示例,但我认为实际上很难以可读的方式编写它。在我真正理解发生了什么之前,我必须逐行运行你的代码

您完全可以使用无点风格(正如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)

这比你的原始版本短了一点,但(我认为)还是可以理解的。

就像托马斯评论的那样,我在我的原始帖子中没有考虑数字要求。下面是我的更正版本:

"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

这与Gustavo发布的内容大致相同。

就像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

这与Gustavo发布的内容大致相同。

在效率方面,不是将字符串中的每个字符单独转换为字符串,这样您就可以将其转换为整数

|> Seq.map (string >> int)
我会将字符直接转换为数字:

|> Seq.map (Char.GetNumericValue >> int)

这样可以减少要收集的垃圾,尽管我还没有对其进行基准测试,但我希望它会更快。

从效率上讲,不是将字符串中的每个字符单独转换为字符串,这样您就可以将其转换为整数

|> Seq.map (string >> int)
我会将字符直接转换为数字:

|> Seq.map (Char.GetNumericValue >> int)

这会减少要收集的垃圾,虽然我还没有对其进行基准测试,但我希望它会更快。

从您的问题描述中,我不明白为什么需要第4-6行将int转换为string再转换为int。将数字加倍后,只需求和。@LeafGarland,因为要求对加倍数字的位数求和。也就是说,
2+4+6+8+(1+0)+(1+2)=24
没有第4-6行,结果是42,而不是24。从您的问题描述中,我不明白为什么需要第4-6行将整数转换为字符串再转换为整数。将数字加倍后,只需求和。@LeafGarland,因为要求对加倍数字的位数求和。也就是说,
2+4+6+8+(1+0)+(1+2)=24
如果没有第4-6行,结果是42,而不是24。但是您的代码正在做其他事情:-)OP的版本不会添加乘以2的值,而是它们的数字。但是您的代码正在做其他事情:-)OP的版本不会添加乘以2的值,但是取而代之的是他们的digits.Char.GetNumericValue:朋友不允许朋友通过字符串将字符转换为整数。:)Char.GetNumericValue:好友不允许好友通过字符串将字符转换为整数。:)