Writing code in F# in most cases results in very condense an intuitive work. This piece of code looks somehow imperative and inconvenient to me.
timesis an array of float values
Lines inside the file times.csv always look like that:
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
averagegenerates an average of the values, dropping the lowest and highest timegetAllSubsetsOfLengthNcreates a sequence of all consecutive subsets of lengthn. Is there a ‘nicer’ solution to that? Or does already exist something like that inside the F# core?bestAverageOfNfinds the lowest average of all the subsets
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
What I am looking for are nicer, shorter or easier solutions. Every useful post will be upvoted, of course 🙂
Without much thinking, there are some basic functional refactorings you can make. For example, in the calculation of
bestAverageOfN, you can use function composition:Other than this and the suggestion by desco, I don’t think there is anything I would change. If you don’t use your special
averagefunction anywhere in the code, you could write it inline as a lambda function, but that really depends on your personal preferences.Just for the sake of generality, I would probably make
timesan argument ofbestAverageOfN: