gpt4 book ai didi

f# - 在 F# 中继续使用相同的列表

转载 作者:行者123 更新时间:2023-12-05 01:18:30 25 4
gpt4 key购买 nike

我正在开发一个 F# 程序,该程序读取文件并根据每一行的事件执行特定操作。

例如,如果行中的第一个词是 create,我会向列表中添加一个元素,如果是 delete,我会从列表中删除一个元素,如果是 modify,我会修改列表中的值。

现在我正在使用 map ,它只对每一行应用 processEventType 函数,但我需要一种方法来继续处理相同的列表。

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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com