List 如何在f#中编辑可变列表中的项目,并允许列表中的其他项目保留其值?
我在f#named tickets中创建了一个列表,其中包含10条名为Ticket的记录。这些记录都用它们的特定座位号和空客户名称初始化List 如何在f#中编辑可变列表中的项目,并允许列表中的其他项目保留其值?,list,f#,mutable,List,F#,Mutable,我在f#named tickets中创建了一个列表,其中包含10条名为Ticket的记录。这些记录都用它们的特定座位号和空客户名称初始化 type Ticket = {seat:int; customer:string} let mutable tickets = [for n in 1..10 -> {Ticket.seat = n; Ticket.customer = ""}] 我想编写一个函数,在列表中预订一个特定的座位(在座位上添加客户姓名)。 如何编辑列表中的某个项目,而使
type Ticket = {seat:int; customer:string}
let mutable tickets = [for n in 1..10 -> {Ticket.seat = n; Ticket.customer = ""}]
我想编写一个函数,在列表中预订一个特定的座位(在座位上添加客户姓名)。
如何编辑列表中的某个项目,而使其他项目仍保留其值功能性F#列表类型是不可变的,这意味着您无法更改它。使用它的典型方式是返回一个新的、修改过的副本
为此,您可以编写一个函数bookSeat
,该函数将list
与number&new name结合起来,生成一个新的list
,其中一个字段已更新:
let bookSeat seatNo name tickets =
tickets |> List.map (fun ticket ->
if ticket.seat = seatNo then { ticket with customer = name }
else ticket )
bookSeat 3 "Tomas" tickets
下面是一种使用可变(参考单元格)票证列表的方法: 显然,如果您想
添加
座位,而不是用所有明显的座位初始化它们,那么您也可以使票证
本身可变
更好的方法(?)
但我认为这是错误的做法——我认为你想要一张地图:
type Ticket = {seat:int; customer:string}
type Tickets = Map<int, Ticket>
let bookSeat seat name (tickets : Tickets) =
match Map.tryFind seat tickets with
| Some oldTicket ->
tickets
|> Map.remove seat
|> Map.add seat { oldTicket with customer = name }
| None ->
tickets
|> Map.add seat { seat = seat; customer = name }
在这里,您不必到处传递票证
——它们将在适当的位置发生变异(但是票证
——对象本身仍然是不可变的)
请注意,现在这不是线程安全的,所以要小心。我认为这里最惯用的方法是简单地使用
字符串数组。如果您事先知道大小,并且希望能够对其进行更新,那么这就是最惯用的满足这两种需求的结构。所以
// create 10-element string array initialized with null
let (tickets : string array) = Array.zeroCreate 10
...
tickets.[3] <- "New Customer"
//创建用null初始化的10元素字符串数组
let(票证:字符串数组)=array.zeroCreate 10
...
票。[3]你在哪一部分卡住了?@JohnPalmer我在某处读到,在f#中,如果我想更改列表中的项目,我必须创建一个新列表。这就是我想到的。但新列表现在只有一项。let bookTicket()=Console.WriteLine(“输入座位号:”)let seatNo=int(Console.ReadLine())Console.WriteLine(“输入客户名称:”)let customerName=string(Console.ReadLine())tickets@CharlesUko,这是真的,在这种情况下(如果您真的想改变情况)我只想使用System.Collection.Generic.list这几乎是这个问题的重复:@JohnPalmer很好的观点-我认为(功能)列表无论如何都是错误的数据表示形式
type Ticket = {seat:int; customer:string}
let tickets = System.Collections.Generic.Dictionary<int, Ticket>()
let bookSeat seat name =
match tickets.TryGetValue seat with
| (true, oldTicket) ->
tickets.[seat] <- { oldTicket with customer = name }
| (false, _) ->
tickets.[seat] <- { seat = seat; customer = name }
// create 10-element string array initialized with null
let (tickets : string array) = Array.zeroCreate 10
...
tickets.[3] <- "New Customer"