3

学习 f# 使用 fparsec 解析一些分隔数据。我正在使用 sepBy 来获取结果列表并过滤掉空结果。我不想要空的项目,但我确实想知道这些项目的位置。有没有更好的方法来获取索引而不是 List.mapi,然后过滤掉空的?分隔数据内部将有其他分隔数据(代表子项)。

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

结果:

[{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;}]

稍后我将需要支持更复杂的层次结构,并且我想避免再编写 5-6 个函数,如“cleanPipes”和“cleanCarrots”,然后再编写另外 5-6 个函数,如“zipPipes”和“zipCarrots”。

4

0 回答 0