使用镜头将键和值添加到嵌套地图
Using lens to add key and value to a nested Map
我正在努力解决使用 Aeson 镜片操作 JSON 的问题。我的任务很简单,就是向 JSON 中的嵌套对象添加一个键。我能够通过以下方式更改现有密钥:
> :set -XOverloadedStrings
> import Control.Lens
> import Data.Aeson
> import Data.Aeson.Lens
> "{ \"a\": { \"b\": 10 } }" & key "a" . key "b" .~ String "jee"
"{\"a\":{\"b\":\"jee\"}}"
但是当我试图让它处理新密钥时,它只是默默地添加失败:
> "{ \"a\": { \"b\": 10 } }" & key "a" . key "c" .~ String "jee"
"{\"a\":{\"b\":10}}"
当然是我做错了什么,但我想我已经没法理解到底是什么了。
你能给我指出正确的方向吗?
谢谢!
key
基于 ix
,其文档表明它不够强大,无法执行您想要的操作并指向 Control.Lens.At.at
。我很确定这应该对你有用。基本思想是,您从 _Object
棱镜开始,将 JSON 文本变成一个对象,然后使用 at key
将透镜 作为 Maybe
。然后,您可以将其更改为 Just
您想要的。
只要您要走的路径上的所有对象都存在,这将非常有效。如果您想(可能)从无到有并创建一个 single-field 对象链,您可能会发现事情更烦人。幸运的是,您可能不需要这样做。
正如 dfeuer 所指出的,at
可以插入映射,而 key
和 ix
仅遍历存在的元素。我们可以做到以下几点:
> "{ \"a\": { \"b\": 10 } }" & key "a" . _Object . at "c" ?~ String "foo"
"{\"a\":{\"b\":10,\"c\":\"foo\"}}
at
是一个聚焦在Maybe element
-s上的镜头,设置为Just
可以插入某个元素,设置为Nothing
可以移除。 at "c" ?~ String "foo"
与 at "c" .~ Just (String "foo")
相同。
如果我们想做嵌套插入,我们可以使用non
定义一个要插入的默认值:
> "{ \"a\": { \"b\": 10 } }" & key "a" . _Object . at "c" . non (Object mempty) . _Object . at "d" ?~ String "foo"
"{\"a\":{\"b\":10,\"c\":{\"d\":\"foo\"}}}"
这是一口,所以我们可以分解出一些部分:
> let atKey k = _Object . at k
> "{ \"a\": { \"b\": 10 } }" & key "a" . atKey "c" . non (Object mempty) . atKey "d" ?~ String "foo"
我正在努力解决使用 Aeson 镜片操作 JSON 的问题。我的任务很简单,就是向 JSON 中的嵌套对象添加一个键。我能够通过以下方式更改现有密钥:
> :set -XOverloadedStrings
> import Control.Lens
> import Data.Aeson
> import Data.Aeson.Lens
> "{ \"a\": { \"b\": 10 } }" & key "a" . key "b" .~ String "jee"
"{\"a\":{\"b\":\"jee\"}}"
但是当我试图让它处理新密钥时,它只是默默地添加失败:
> "{ \"a\": { \"b\": 10 } }" & key "a" . key "c" .~ String "jee"
"{\"a\":{\"b\":10}}"
当然是我做错了什么,但我想我已经没法理解到底是什么了。
你能给我指出正确的方向吗?
谢谢!
key
基于 ix
,其文档表明它不够强大,无法执行您想要的操作并指向 Control.Lens.At.at
。我很确定这应该对你有用。基本思想是,您从 _Object
棱镜开始,将 JSON 文本变成一个对象,然后使用 at key
将透镜 作为 Maybe
。然后,您可以将其更改为 Just
您想要的。
只要您要走的路径上的所有对象都存在,这将非常有效。如果您想(可能)从无到有并创建一个 single-field 对象链,您可能会发现事情更烦人。幸运的是,您可能不需要这样做。
正如 dfeuer 所指出的,at
可以插入映射,而 key
和 ix
仅遍历存在的元素。我们可以做到以下几点:
> "{ \"a\": { \"b\": 10 } }" & key "a" . _Object . at "c" ?~ String "foo"
"{\"a\":{\"b\":10,\"c\":\"foo\"}}
at
是一个聚焦在Maybe element
-s上的镜头,设置为Just
可以插入某个元素,设置为Nothing
可以移除。 at "c" ?~ String "foo"
与 at "c" .~ Just (String "foo")
相同。
如果我们想做嵌套插入,我们可以使用non
定义一个要插入的默认值:
> "{ \"a\": { \"b\": 10 } }" & key "a" . _Object . at "c" . non (Object mempty) . _Object . at "d" ?~ String "foo"
"{\"a\":{\"b\":10,\"c\":{\"d\":\"foo\"}}}"
这是一口,所以我们可以分解出一些部分:
> let atKey k = _Object . at k
> "{ \"a\": { \"b\": 10 } }" & key "a" . atKey "c" . non (Object mempty) . atKey "d" ?~ String "foo"