Aeson:将动态键解析为类型字段 [英] Aeson: parsing dynamic keys as type field

查看:69
本文介绍了Aeson:将动态键解析为类型字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设有一个类似JSON的

Let's say there is a JSON like:

{
  "bob_id" : {
    "name": "bob",
    "age" : 20
  },
  "jack_id" : {
    "name": "jack",
    "age" : 25
  }
}

是否可以使用如下定义的Person将其解析为[Person]?

Is it possible to parse it to [Person] with Person defined like below?

data Person = Person {
   id   :: Text
  ,name :: Text
  ,age  :: Int
}

推荐答案

您不能从字面上定义[Person]的实例,因为aeson已经包含了[a]的实例,但是您可以创建一个新类型并提供一个实例为此.

You cannot define an instance for [Person] literally, because aeson already includes an instance for [a], however you can create a newtype, and provide an instance for that.

Aeson还包括实例FromJSON a => FromJSON (Map Text a),这意味着aeson知道如何解析某事物,它知道如何解析该事物的字典.

Aeson also includes the instance FromJSON a => FromJSON (Map Text a), which means if aeson knows how to parse something, it knows how to parse a dict of that something.

您可以定义类似于dict中的值的临时数据类型,然后使用Map实例定义FromJSON PersonList,其中newtype PersonList = PersonList [Person]:

You can define a temporary datatype resembling a value in the dict, then use the Map instance to define FromJSON PersonList, where newtype PersonList = PersonList [Person]:

data PersonInfo = PersonInfo { infoName :: Text, infoAge :: Int }

instance FromJSON PersonInfo where
    parseJSON (Object v) = PersonInfo <$> v .: "name" <*> v .: "age"
    parseJSON _ = mzero

data Person = Person { id :: Text, name :: Text, age :: Int }
newtype PersonList = PersonList [Person]

instance FromJSON PersonList where
    parseJSON v = fmap (PersonList . map (\(id, PersonInfo name age) -> Person id name age) . M.toList) $ parseJSON v

这篇关于Aeson:将动态键解析为类型字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆