Last active
August 29, 2015 14:03
-
-
Save seankearon/20d6b0c1c0e10bbd13dd to your computer and use it in GitHub Desktop.
Parsing sections from a log file using F#
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Code for review posted here: http://codereview.stackexchange.com/questions/55554/parsing-sections-from-a-log-file-using-f | |
// Here are the "lines" from my "log file". | |
let lines = [1 .. 25] |> List.map (fun x -> x.ToString()) | |
// For this exercise, section criteria is divisibility by 5. | |
// val DivisibleByFive : s:string -> bool | |
let DivisibleByFive (s:string) = | |
System.Int32.Parse(s) % 5 = 0 | |
// I am going to use the following type to hold the information | |
// from each section of the log. | |
type Section (lines:string list) = | |
member x.Lines = lines | |
// Read a single section from the top of the log (based on: http://fssnip.net/iV). | |
// val GetSection : lines:string list -> Section * string list | |
let GetSection (lines:string list) = | |
let rec getSection (l:string list) result = | |
match l with | |
| h::t when DivisibleByFive h -> | |
let values = h::result |> List.rev | |
(new Section(values), t) | |
| h::t when not (DivisibleByFive h) -> | |
getSection t (h::result) | |
| _ -> | |
(new Section(result), []) | |
getSection lines [] | |
// Get a list of all sections from the log. | |
// val GetSections : lines:string list -> Section list | |
let GetSections (lines:string list) = | |
let rec getSections (l:string list) result = | |
match GetSection l with | |
| (a, []) -> (a::result) | |
| (a, b) -> getSections b (a::result) | |
getSections lines [] |> List.rev | |
let sections = GetSections lines | |
sprintf "Parsed %d section from the log:" sections.Length |> System.Console.WriteLine | |
for i in sections do | |
sprintf " Section starting with %s" i.Lines.[0] |> System.Console.WriteLine |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This is the refactored version following comments by mjolka here: http://codereview.stackexchange.com/a/55606/4813 | |
// Here are the "lines" from my "log file". | |
let lines = [1 .. 25] |> List.map (fun x -> x.ToString()) | |
// For this exercise, section criteria is divisibility by 5. | |
// val DivisibleByFive : s:string -> bool | |
let DivisibleByFive (s:string) = | |
System.Int32.Parse(s) % 5 = 0 | |
// I am going to use the following type to hold the information | |
// from each section of the log. | |
type Section (lines:string list) = | |
member x.Lines = lines | |
/// <summary> | |
/// Splits the given sequence into non-empty contiguous subsequences, such | |
/// that the last element of every subsequence (except possibly the last) | |
/// satisfies the given predicate. No other elements satisfy the predicate. | |
/// </summary> | |
/// <example> | |
/// <c> | |
/// let even x = x % 2 = 0 | |
/// printfn "%A" (splitAtEach even (seq { 1 .. 3 })) | |
/// printfn "%A" (splitAtEach even (seq { 1 .. 4 })) | |
/// </c> | |
/// The output is: | |
/// <c> | |
/// seq [[1; 2]; [3]] | |
/// seq [[1; 2]; [3; 4]] | |
/// </c> | |
/// </example> | |
let splitAtEach (predicate : 'T -> bool) (xs : seq<'T>) : seq<'T list> = | |
let section = new ResizeArray<'T>() | |
seq { | |
for x in xs do | |
section.Add x | |
if predicate x then | |
yield Seq.toList section | |
section.Clear() | |
if section.Any() then | |
yield Seq.toList section | |
} | |
let sections = | |
splitAtEach DivisibleByFive lines | |
|> Seq.map (fun lines -> new Section(lines)) | |
|> Seq.toList | |
printfn "Parsed %d section from the log:" sections.Length | |
sections |> List.iter (fun section -> printfn " Section starting with %s" section.Lines.[0]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment