2017-08-17 72 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(&&)'。現在它就像一個魅力! –