首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >FP -压缩和‘好’代码

FP -压缩和‘好’代码
EN

Stack Overflow用户
提问于 2011-05-07 11:45:09
回答 4查看 207关注 0票数 1

在大多数情况下,用F#编写代码会使直观的工作变得非常简练。在我看来,这段代码似乎是命令式的,而且不方便。

  • times是浮点值

的数组。

文件times.csv中的行通常如下所示:

代码语言:javascript
复制
Mai 06 2011 05:43:45 nachm.,00:22.99
Mai 04 2011 08:59:12 nachm.,00:22.73
Mai 04 2011 08:58:27 nachm.,00:19.38
Mai 04 2011 08:57:54 nachm.,00:18.00

  • average生成值的平均值,删除最低和最高的time
  • getAllSubsetsOfLengthN将创建一个长度为n的所有连续子集的序列。有什么更好的解决办法吗?或者,是否已经存在类似于core?
  • bestAverageOfN中的F#,在所有子集中,

中的平均值最低?

代码语言:javascript
复制
let times =
    File.ReadAllLines "times.csv"
    |> Array.map (fun l -> float (l.Substring((l.LastIndexOf ':') + 1)))
let average set =
    (Array.sum set - Array.min set - Array.max set) / float (set.Length - 2)
let getAllSubsetsOfLengthN n (set:float list) =
    seq { for i in [0 .. set.Length - n] -> set
                                            |> Seq.skip i
                                            |> Seq.take n }
let bestAverageOfN n =
    times
    |> Array.toList
    |> getAllSubsetsOfLengthN n
    |> Seq.map (fun t -> t
                         |> Seq.toArray
                         |> average)
    |> Seq.min

我正在寻找的是更好,更短或更容易的解决方案。当然,每一个有用的职位都会被更新:)

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-05-07 12:10:44

无需过多思考,您就可以进行一些基本的功能重构。例如,在计算bestAverageOfN时,可以使用函数组合:

代码语言:javascript
复制
let bestAverageOfN n =
    times
    |> Array.toList
    |> getAllSubsetsOfLengthN n
    |> Seq.map (Seq.toArray >> average)
    |> Seq.min

除了这个和德科的建议,我不认为有什么我会改变的。如果代码中没有使用特殊的average函数,则可以将其内联为lambda函数,但这实际上取决于您的个人喜好。

只是为了一般性起见,我可能会把times作为bestAverageOfN的一个论点。

代码语言:javascript
复制
let bestAverageOfN n times =
    times
    |> Seq.windowed n
    |> Seq.map (fun set ->
           (Array.sum set - Array.min set - Array.max set) / float (set.Length - 2))
    |> Seq.min
票数 3
EN

Stack Overflow用户

发布于 2011-05-07 12:16:25

我想,getAllSubsetsOfLengthN可以用Seq.windowed代替

因此,bestAverageOfN的外观如下:

代码语言:javascript
复制
let bestAverageOfN n =
    times
    |> Seq.windowed n
    |> Seq.map average
    |> Seq.min
票数 4
EN

Stack Overflow用户

发布于 2011-05-07 14:01:06

既然您提到了解析输入的regex,我想我会向您展示这样的解决方案。这很可能是过分的,但它也是一个更实用的解决方案,因为正则表达式是声明性的,而子字符串的内容则更有必要。Regex也很好,因为如果输入的结构发生变化,那么Regex就更容易增长,而索引子字符串的内容可能会变得混乱,我试图完全避免它。

首先是一些活跃的模式,

代码语言:javascript
复制
open System.Text.RegularExpressions
let (|Groups|_|) pattern input =
    let m = Regex.Match(input, pattern)
    if m.Success then
        Some([for g in m.Groups -> g.Value] |> List.tail)
    else
        None

open System
let (|Float|_|) input =
    match Double.TryParse(input) with
    | true, value -> Some(value)
    | _ -> None

采用@ildjarn的times实现:

代码语言:javascript
复制
let times =
    File.ReadAllLines "times.csv"
    |> Array.map (function Groups @",.*?:(.*)$" [Float(value)] -> value)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5920812

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档