更改不可变对象 F#

9

我觉得这个标题是错误的,但是无法创造一个反映我想要实现的抽象标题。

我正在编写一个函数,它调用服务并检索JSON字符串数据。该函数使用 JSON类型提供程序解析字符串。在某些条件下,我想修改JSON对象上的属性,然后返回修改后对象的字符串。因此,如果调用的响应如下:

{"property1" : "value1","property2" : "value2", "property3": "value3" }

我希望将property3更改为新值,然后返回JSON字符串。
如果JsonProvider是可变的,这将是一个类似于以下练习:
type JsonResponse = 
        JsonProvider<""" {"property1" : "value1", 
                          "property2" : "value2",
                          "property3": "value3" } """>

let jsonResponse = JsonResponse.Parse(response)
jsonResponse.Property3 <- "new value"
jsonResponse.ToString()

然而,由于属性无法设置,这并不起作用。我正在尝试确定解决此问题的最佳方法。我很乐意根据原始响应初始化一个新对象,但是带有修改后的参数,但我不确定是否有轻松的方法来实现这一点。
供参考,JSON对象比给出的平面示例复杂得多,并包含深层次结构。

如果jsonResponse的类型是记录,你可以这样做:{ jsonRespose with Property3 = "new value" }。但似乎不起作用。 - svick
1
不幸的是,类型提供程序目前无法创建记录类型。 - Ross McKinlay
https://github.com/fsharp/FSharp.Data/issues/178 - Dzmitry Lahoda
1个回答

7

是的,您需要创建一个新的对象,更改您想要的位,并使用现有对象的值作为其余部分。我们不久前为XML和JSON类型提供程序添加了写API。您会注意到表示JSON的类型上有构造函数。您可以在此链接底部看到其使用示例。


2
谢谢您的回答。我已经尝试过这个方法,唯一能让它工作的方式是在构造函数中指定JSON的所有属性作为参数。这对于我给出的示例let newThing = JsonResponse.Example("value2", "value3", "value3")可以工作,但对于一个大的对象图来说,这并不实际。您是否有任何见解,如何以更“挑剔”的方式完成此操作,即仅将旧对象的特定属性修改为新对象。我想在新对象上设置的属性在层次结构中有几层。 - AlexC
1
写入API相对较新,我们添加了完整的构造函数支持,并且能够从其他JsonValue对象复制(底层类型擦除)-这使您可以在共享其中嵌套相同子类型的JSON类型提供程序类型之间复制数据。 对于您想要的内容,可能需要类型提供程序中的一些新支持。 我同意这将是有用的,您应该在FSharp.Data github上打开一个问题(或自己去做!)。 - Ross McKinlay
目前似乎不可能实现:https://github.com/fsharp/FSharp.Data/issues/914#issuecomment-189069108 - Jon49

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接