我有一个分隔的数据字符串,例如
a~b~c~d~e~f~g~h~i~j~k~l~...
dog~cat~fish~parrot~mother~father~child~grandparent~...
hello~hi~greetings~yo
我想将数据加载到类型
的数组/序列中type myType {
first: string;
second: string;
third: string;
fourth:string;
}
所以我最终得到了数组/ seq中的3个对象。我一直在乱用for循环来做这件事,但感觉非常迫切。我如何使用功能成语来实现这一目标?
编辑:我应该澄清,分隔数据可以是可变长度的,尽管分隔项的数量应该总是4的倍数。因此,每次迭代,我都想剥离4个输入数据加载将它们放入类型中,一旦消耗完所有数据,返回一个Array / seq。编辑2:所以我最终得到了类似的东西
let createValues(data: string) =
let splitValues(valueString) =
let rec splitData acc = function
| a :: b :: c :: d :: xs -> splitData ({ first=a; second=b; third=c; fourth=d } :: acc) xs
| [] -> acc
| _ -> failwith "uneven data"
splitData [] valueString
splitValues (data.Split [|'~'|] |> Array.toList)
THX
答案 0 :(得分:5)
您的类型只包含单个字符 - 假设数据始终由单个字符组成,则不需要分隔符。这是将数据映射到类型列表的一种方法,这只有在数据中的字符数可以被4整除时才有效,但是可以使用可变大小的输入。
let data = "a~b~c~d~e~f~g~h~i~j~k~l~m~n~o~p"
let splitData data =
let rec aux acc = function
| a::b::c::d::xs -> aux ({ first=a; second=b; third=c; fourth=d } :: acc) xs
| [] -> acc
| _ -> failwith "uneven data"
aux [] data
let output = splitData (data.Replace("~","").ToCharArray() |> Array.toList)
答案 1 :(得分:3)
尽管已经给出了很好的答案,如果您需要确保输入数据格式完全符合您的规范,您可以像这样解析它:
let readObjects inputString =
let rec readObjectsAux input =
seq {
match input with
| a :: '~' :: b :: '~' :: c :: '~' :: d :: rest ->
yield { first = a; second = b; third = c; fourth = d }
match rest with
| '~' :: rest -> yield! (readObjectsAux rest)
| [] -> ()
| _ -> failwith "bad input"
| [] -> ()
| _ -> failwith "bad input"
}
readObjectsAux <| (List.ofSeq inputString)
通过这种方式,您可以确保您的角色始终位于四重奏中,并且它们始终只分隔一个'~'
。
答案 2 :(得分:2)
如果每个字段只有一个char
(在这种情况下,我没有看到分隔符中的点,所以我省略了它),你可以这样做:
File.ReadAllLines(@"C:\data.txt")
|> Array.mapi (fun n line ->
match line.ToCharArray() with
| [|a;b;c;d;e;f;g;h;i;j;k;l|] ->
let t1 = {first=a; second=b; third=c; fourth=d}
let t2 = {fifth=e; sixth=f; seventh=g; eighth=h}
let t3 = {ninth=i; tenth=j; eleventh=k; twelfth=l}
(t1, t2, t3)
| _ -> failwithf "Can't parse line %d" (n+1))
如果需要分隔符,可以将其更改为:
match line.Split('~') with
| [|a;b;c;d;e;f;g;h;i;j;k;l|] ->
let t1 = {first=a.[0]; second=b.[0]; third=c.[0]; fourth=d.[0]}
...