我正在研究一个F#程序,该程序读取文件并根据每一行的事件执行特定的操作。
例如,如果该行的第一个单词为create,则向列表中添加一个元素;如果删除,则从列表中删除一个元素;如果Modify,则修改列表中的值。
现在,我正在使用仅将processEventType函数应用于每行的map,但是我需要一种方法来继续处理相同的列表。
let processEventType (words:string[]) myList =
match words with
| [| event; var1; var2; var3 |] when event = "create" -> Map.add var2 var3 myList
| [| event; var1; var2; |] when event = "delete" -> Map.remove "2" myList
| _ -> failwith "Error processing event"
let test (lines: list<string>) =
List.map (fun line -> (processEventType(splitLine line) myList)) lines
非常感谢任何帮助,因为我是函数式编程和F#的新手。
最佳答案
如果我正确理解了您的问题,那是processEventType
不允许您一遍又一遍地使用相同的列表。如果您将事件应用于列表,则该事件的结果列表不会用于下一个事件。
由于您是SO的新手,因此我无法查看您的历史来确定您的知识库,因此无法为您提供相关思想的参考和指导。
基本上对于processEventType
,您需要返回列表(newList
)作为每个模式匹配的最终声明
// Signature of processEventType
val processEventType : string * string list -> theList:string list -> string list
然后在调用
processEventType
的函数中获取结果,然后使用递归函数将其传递回processEventType
。 let rec processEvents commands theList =
match commands with
| (command::t) ->
let newList = processEventType command theList
processEvents t newList
| [] -> theList
对于这个答案,当其他人正确使用像
let rec
这样的功能时,我将使用List.map
;初剪只是个人喜好。我还可以使用|>
对其进行大量重构,但是如果您想插入printfn
看看正在发生的事情,或者跟着调试器一起使用,则可以不用重构它。该代码比您拥有的代码大得多,这是因为使用
F# immutable list
可以使我像所指出的那样传递结果,因此我对输入进行了更多的处理,并添加了一些功能以列表形式处理数据。namespace Workspace
module main =
[<EntryPoint>]
let main argv =
let theList = []
let input : string =
"add 1 2 3 4" + System.Environment.NewLine +
"delete 1 2" + System.Environment.NewLine +
"add 1" + System.Environment.NewLine +
"delete 4 2" + System.Environment.NewLine +
"modify 1 5" + System.Environment.NewLine
let lines = input.Split([| '\n';'\r' |])
let lines = List.ofArray lines
let lines = List.filter (fun (x : string) -> x.Length > 0) lines
let commands = List.map(fun (line:string) -> line.Split([| ' ' |])) lines
let commands = List.map(List.ofArray) commands
let convertCommand (input : string list) : (string * string list) =
let command = List.head input
let values = List.tail input
(command,values)
let commands = List.map(convertCommand) commands
let rec merge master items =
match master,items with
| [],l | l,[] -> l
| x::xs', y::ys' ->
if x = y then x :: (merge xs' ys')
elif x < y then x :: (merge xs' items)
else y :: (merge master ys')
let deleteItems master items =
let deleteItem master item =
let rec deleteItem master item acc =
match master with
| (h::t) when h <> item ->
let acc = h :: acc
deleteItem t item acc
| (h::t) ->
deleteItem t item acc
| [] -> List.rev acc
deleteItem master item []
let rec deleteItemsInner master items =
match items with
| (item::t) ->
let master = deleteItem master item
deleteItemsInner master t
| [] -> master
deleteItemsInner master items
let modifyItems master v1 v2 =
let rec modifyInner master v1 v2 acc =
match master with
| (h::t) when h = v1 ->
let acc = v2 :: acc
modifyInner t v1 v2 acc
| (h::t) ->
let acc = h :: acc
modifyInner t v1 v2 acc
| [] -> List.rev acc
modifyInner master v1 v2 []
let processEventType (event : (string * string list)) (theList : string list) : string list =
let (command,eventValues) = event
match command with
| "add" ->
printfn "Adding: %A" eventValues
let newList = merge theList eventValues
printfn "result: %A" newList
newList
| "delete" ->
printfn "Deleting: %A" eventValues
let newList = deleteItems theList eventValues
printfn "result: %A" newList
newList
| "modify" ->
match eventValues with
| v1::v2::[] ->
printfn "Modifying: %A %A" v1 v2
let newList = modifyItems theList v1 v2
printfn "result: %A" newList
newList
| _ -> failwith "Error with modify parameters"
| _ -> failwith "Error processing event"
let rec processEvents commands theList =
match commands with
| (command::t) ->
let newList = processEventType command theList
processEvents t newList
| [] -> theList
let newList = processEvents commands theList
printfn "theList: %A" newList
printf "Press any key to exit: "
System.Console.ReadKey() |> ignore
printfn ""
0 // return an integer exit code
运行时,将产生以下输出:
Adding: ["1"; "2"; "3"; "4"]
result: ["1"; "2"; "3"; "4"]
Deleting: ["1"; "2"]
result: ["3"; "4"]
Adding: ["1"]
result: ["1"; "3"; "4"]
Deleting: ["4"; "2"]
result: ["1"; "3"]
Modifying: "1" "5"
result: ["5"; "3"]
theList: ["5"; "3"]
Press any key to exit:
关于f# - 在F#中继续使用相同的列表,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36546669/