我正在尝试使用类似这样的数据结构从API解析JSON
{
"en": {
"translation": {
"name": "Name",
"description": ["I am a", "en person"]
}
},
"jp": {
"translation": {
"name": "JP Name",
"description": ["I am a", "jp person"]
}
}
}
因此,我只想将它们解析为类似newtype Translations = Map String String
的东西。语言环境将是键名称,而值将只是JSON翻译的字符串,例如{"name": "Name", "description": ["I am a", en person"]}
,因为该值可能是任意复杂的,因此我很想/需要将其转换为其他Haskell数据结构。
我尝试了多种方法来为parseJSON
编写适当的Translation
,但仍然无法实现。
任何帮助将不胜感激!
答案 0 :(得分:0)
我们可以使用以下方法解码ByteString
:
Prelude Data.Aeson Bs Hm Mp Tx> decode text :: Maybe Object
Just (fromList [("jp",Object (fromList [("translation",Object (fromList [("name",String "JP Name"),("description",Array [String "I am a",String "jp person"])]))])),("en",Object (fromList [("translation",Object (fromList [("name",String "Name"),("description",Array [String "I am a",String "en person"])]))]))])
因此,我们只需要对包装在对象构造函数中的HashMap Text Object
进行映射:
import Data.Aeson
import qualified Data.ByteString.Lazy.Char8 as Bs
import qualified Data.HashMap.Lazy as Hm
import qualified Data.Map as Mp
import qualified Data.Text as Tx
process :: Value -> Maybe (Mp.Map String String)
process (Object m) = Just ((Mp.fromList . map f) (Hm.toList m))
where f (x, y) = (Tx.unpack x, Bs.unpack (encode y))
process _ = Nothing
然后我们获得一个Map String String
包裹在Maybe
中的包(由于两个解码都可能导致处理出错,因此最好使用Maybe
)来映射{{在String
s上有1}} s:
String
话虽这么说,但我不确定您想要的是JSON blob作为值在这里,因为现在无法“查看”该值并检查该元素内部的内容。此外,如果要进行大量查找,当您要检查两个Prelude Data.Aeson Bs Hm Mp Tx> decode text >>= process
Just (fromList [("en","{\"translation\":{\"name\":\"Name\",\"description\":[\"I am a\",\"en person\"]}}"),("jp","{\"translation\":{\"name\":\"JP Name\",\"description\":[\"I am a\",\"jp person\"]}}")])
是否相同时,Text
通常快一个数量级。