2017-08-17 50 views
1

我有一个JSON结构看起来像这样:如何提取满足条件的部分aeson值?

{ 
    "instances": [ 
    { 
     "instanceId": "i-1234", 
     "tags": [ 
     { 
      "value": "author1useast1", 
      "key": "hostname" 
     } 
     ] 
    }, 
    { 
     "instanceId": "i-5678", 
     "tags": [ 
     { 
      "value": "proxy1useast1", 
      "key": "hostname" 
     } 
     ] 
    } 
    ] 
} 

我想获得的所有instances/instanceId的列表,其中instances/tagsauthor1useast1一个hostname

我想过先获得key "instances" . _Values的实例列表,然后将其映射到(instanceId,tags)元组列表中,然后进行过滤。但是,这对我来说看起来效率很低。

有没有更优雅/习惯的方式来做到这一点?

非常感谢!

+0

的惯用方法是分析整个JSON文件,然后写上从产生的ADT过滤功能。 – user2407038

+0

是的,所以我已经有了上面的JSON作为'Value',并且我知道如何过滤例如'instanceId's出来了。但是,我的情况涉及树的不同部分,即“标签”,我想知道如何过滤标签与条件匹配的instanceIds。 –

+0

对不起,我应该已经更清楚了 - 将文档解析为模拟文档特定结构的ADT(例如'data Tag = Tag {value :: Text,key :: Text}; data Instance = Instance {ID: :Text,tag :: Tag}; newtype Instances = Instances [Instance]')。如果JSON格式良好,但与您期望的结构不符,会怎么样?比方说,有一个对象的'instanceId'和'tags'嵌套在其他对象的其中一个标签字段中。任何对'Value'的过滤都不会检测到这个;但是如果你首先解析你自己的ADT,你的文档结构将被强制执行。 – user2407038

回答

2

如果你想用镜头,你可以使用filtered光,为实例:

key "instances" . values 
. filtered (anyOf (key "tags" . values) $ 
    allOf (key "key") (=="hostname") 
    <&&> allOf (key "value") (=="author1useast1")) 
. key "instanceId" 
+0

非常感谢,这就是我一直在寻找的! –

+0

不客气! – freestyle

+0

小附录: 我问hayoo的<&&>,发现它在“cond”和“control-bool”包中,这两个包在我使用的堆栈lts-7.3中都不可用。解决办法是把它自己定义为'liftM2(&&)'。现在它就像一个魅力! –