Learning f# using fparsec to parse some delimited data. I am using sepBy to get a list of results and filtering out the empty results. I don't want items that are empty but I do want to know what position the items were in. Is there a better way to get the index instead of List.mapi and later filtering out empties? The delimited data will have other delimited data inside (represents children).
type result = {value:string; index:int}
type parent = {results:result list; index:int}
let delims = "|^"
let pipeandcarrotdata = "|A^B^C||B|C"
let zipi res = List.mapi (fun i item -> res i item)
let zipPipes = zipi (fun i t -> {results = t; index = i})
let zipCarrots = zipi (fun i t -> {value = t; index = i})
let cleanlist predicate = List.filter (fun i -> predicate i)
let cleanPipes = cleanlist (fun t -> t.results.IsEmpty <> true)
let cleanCarrots = cleanlist (fun t -> t.value <> "")
let collect items = List.mapi (fun i item -> {value = item; index = i}) items
let cleanEmpties items = List.filter (fun item -> item.value <> "") items
let pCarrots = sepBy (manyChars (noneOf delims)) (pstring "^") |>> (zipCarrots >> cleanCarrots)
let pPipes = sepBy pCarrots (pstring "|") |>> (zipPipes >> cleanPipes)
test pPipes pipeandcarrotdata
Result:
[{results = [{value = "A";index = 0;}; {value = "B";index = 1;}; {value = "C";index = 2;}]; index = 1;};
{results = [{value = "B"; index = 0;}]; index = 3;};
{results = [{value = "C"; index = 0;}];index = 4;}]
Later I will need to support a more complex hierarchy and I would like to avoid writing 5-6 more functions like "cleanPipes" and "cleanCarrots" and then another 5-6 functions like "zipPipes" and "zipCarrots".