在大多数情况下,用F#编写代码会使直观的工作变得非常简练。在我看来,这段代码似乎是命令式的,而且不方便。
times是浮点值的数组。
文件times.csv中的行通常如下所示:
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.00average生成值的平均值,删除最低和最高的timegetAllSubsetsOfLengthN将创建一个长度为n的所有连续子集的序列。有什么更好的解决办法吗?或者,是否已经存在类似于core?bestAverageOfN中的F#,在所有子集中,中的平均值最低?
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我正在寻找的是更好,更短或更容易的解决方案。当然,每一个有用的职位都会被更新:)
发布于 2011-05-07 12:10:44
无需过多思考,您就可以进行一些基本的功能重构。例如,在计算bestAverageOfN时,可以使用函数组合:
let bestAverageOfN n =
times
|> Array.toList
|> getAllSubsetsOfLengthN n
|> Seq.map (Seq.toArray >> average)
|> Seq.min除了这个和德科的建议,我不认为有什么我会改变的。如果代码中没有使用特殊的average函数,则可以将其内联为lambda函数,但这实际上取决于您的个人喜好。
只是为了一般性起见,我可能会把times作为bestAverageOfN的一个论点。
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发布于 2011-05-07 12:16:25
我想,getAllSubsetsOfLengthN可以用Seq.windowed代替
因此,bestAverageOfN的外观如下:
let bestAverageOfN n =
times
|> Seq.windowed n
|> Seq.map average
|> Seq.min发布于 2011-05-07 14:01:06
既然您提到了解析输入的regex,我想我会向您展示这样的解决方案。这很可能是过分的,但它也是一个更实用的解决方案,因为正则表达式是声明性的,而子字符串的内容则更有必要。Regex也很好,因为如果输入的结构发生变化,那么Regex就更容易增长,而索引子字符串的内容可能会变得混乱,我试图完全避免它。
首先是一些活跃的模式,
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实现:
let times =
File.ReadAllLines "times.csv"
|> Array.map (function Groups @",.*?:(.*)$" [Float(value)] -> value)https://stackoverflow.com/questions/5920812
复制相似问题