我目前正在使用F#完成一个项目。我对函数式编程非常陌生,尽管我熟悉列表项是不可变的,但仍然存在一些问题:
我有一个格式的字符串列表
["(states, (1,2,3,4,5))"; "(alpha, (1,2))"; "(final, (1))"]
我想做的是将每个列表元素转换成自己的列表,而无需使用逗号分隔字符串。输出应如下所示:
["1"; "2"; "3"; "4"; "5"]
["1"; "2"]
["1"]
我发现了无数种连接列表元素的方法,到目前为止,我的最佳猜测(正在展开或类似的尝试)是徒劳的。任何帮助或朝着正确方向的观点将不胜感激。谢谢!
您可以使用.NET中的内置字符串处理API来实现此目的。您不必特别花哨,但可以帮助通过string
API提供一些苗条的咖喱适配器:
open System
let removeWhitespace (x : string) = x.Replace(" ", "")
let splitOn (separator : string) (x : string) =
x.Split([| separator |], StringSplitOptions.RemoveEmptyEntries)
let trim c (x : string) = x.Trim [| c |]
唯一棘手的步骤是一旦您习惯splitOn
拆分"(states, (1,2,3,4,5))"
为[|"(states"; "1,2,3,4,5))"|]
。现在,您有一个包含两个元素的数组,并且需要第二个元素。您可以通过以下方法进行操作:首先获取Seq.tail
该数组,丢弃第一个元素,然后获取Seq.head
结果序列,为您提供剩余序列的第一个元素。
使用这些构造块,您可以像这样提取所需的数据:
let result =
["(states, (1,2,3,4,5))"; "(alpha, (1,2))"; "(final, (1))"]
|> List.map (
removeWhitespace
>> splitOn ",("
>> Seq.tail
>> Seq.head
>> trim ')'
>> splitOn ","
>> Array.toList)
结果:
val result : string list list = [["1"; "2"; "3"; "4"; "5"]; ["1"; "2"]; ["1"]]
最不安全的部分是Seq.tail >> Seq.head
组合。如果输入列表中的元素少于两个,则失败。一种更安全的替代方法是使用类似以下trySecond
帮助器函数的方法:
let trySecond xs =
match xs |> Seq.truncate 2 |> Seq.toList with
| [_; second] -> Some second
| _ -> None
使用此功能,您可以重写数据提取功能,使其更强大:
let result' =
["(states, (1,2,3,4,5))"; "(alpha, (1,2))"; "(final, (1))"]
|> List.map (removeWhitespace >> splitOn ",(" >> trySecond)
|> List.choose id
|> List.map (trim ')' >> splitOn "," >> Array.toList)
结果与以前相同。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句