我想要一些Haskell的帮助,我对语言和函数式编程都很陌生(在JavaScript中已经接触过它,但没什么用)
我需要解析由参数定义的不同类型的JSON对象,并首先存储它们以供以后处理,例如:
{-# LANGUAGE OverloadedStrings, DeriveGeneric #-}
import Data.Aeson
import Data.Text
import Control.Applicative
import Control.Monad
import qualified Data.ByteString.Lazy as B
import GHC.Generics
data Agent =
Agent { agentId :: Text
, name :: Text
, primary_skillset :: [Text]
, secondary_skillset :: [Text]
} deriving Show
instance FromJSON Agent where
parseJSON (Object v) =
Agent <$> v .: "id"
<*> v .: "name"
<*> v .: "primary_skillset"
<*> v .: "secondary_skillset"
parseJSON _ = mzero
instance ToJSON Agent where
toJSON (Agent agentId name primary_skillset secondary_skillset) =
object [ "id" .= agentId
, "name" .= name
, "primary_skillset" .= primary_skillset
, "secondary_skillset" .= secondary_skillset
]
jsonFile :: FilePath
jsonFile = "sample-input.json"
-- Read the local copy of the JSON file.
getJSON :: IO B.ByteString
getJSON = B.readFile jsonFile
main :: IO ()
main = do
-- Get JSON data and decode it
d <- (eitherDecode <$> getJSON) :: IO (Either String [Agent])
-- If d is Left, the JSON was malformed.
-- In that case, we report the error.
-- Otherwise, we perform the operation of
-- our choice. In this case, just print it.
case d of
Left err -> putStrLn err
Right ps -> print ps
这意味着我需要存储3种不同类型的数组,这些数组将来必须互相交互。
到目前为止,通过教程,我已经找到足够的指令,这使我能够使用fromJSON和toJSON打印一个对象的简单代码,我可以将其复制到其他对象,但我仍然不知道如何抓取对象通过第一个参数(new_agent,new_job,job_request),在决定如何解析之前:
#include <vector>
using namespace std;
struct TempData {
vector<int> data;
TempData() {
for(int i = 0; i < 100; i++) data.push_back(i);
}
// vector<int> GetData() { // function 1
// return move(data);
// }
vector<int>&& GetData() { // function 2
return move(data);
}
};
int main() {
vector<int> v;
{
TempData td;
v = td.GetData();
}
}
我正在寻找以下问题的答案(如果可能的话,还有代码片段):
如何通过id抓取对象中的对象,然后将其添加到数组中
将对象存储在数组中之后,我该如何&#34;迭代&#34;每当我需要再次使用那个特定信息时(通过对象键搜索)
如何在数组中分配(更新)JSON,并将其保留在那里
答案 0 :(得分:1)
下面的代码可以帮助您完成您想要做的事情。它使用与user2407038建议的技术类似的技术。将三种不同的数据类型收集到总和类型中:SomeObj
。为SomeObj
类型创建了三个不同的解析器,第一个成功的解析器是使用的 - 另外两个未使用。
如果可能,我让编译器自动定义JSON功能。
我添加了其他代码,通过转换回JSON然后解码该JSON来验证结果。
&#34; DuplicateRecordFields
&#34;需要使用语言扩展程序,以便Agent
和Job
都有id
字段。
解析JSON后,您应该能够使用List
功能来执行您所描述的搜索和更新操作。
{-# LANGUAGE OverloadedStrings, DeriveGeneric #-}
{-# LANGUAGE DuplicateRecordFields #-}
import Data.Aeson
import Data.Text
import Control.Applicative
import Control.Monad
import qualified Data.ByteString.Lazy as B
import GHC.Generics
data Agent =
Agent { id :: Text
, name :: Text
, primary_skillset :: [Text]
, secondary_skillset :: [Text]
} deriving (Show, Generic)
instance FromJSON Agent
instance ToJSON Agent
data Job =
Job { id :: Text
, tipo :: Text
, urgent :: Bool
} deriving (Show, Generic)
instance FromJSON Job
instance ToJSON Job
newtype JobRequest =
JobRequest { agent_id :: Text
} deriving (Show, Generic)
instance FromJSON JobRequest
instance ToJSON JobRequest
data SomeObj =
AnAgent Agent
| AJob Job
| AJobRequest JobRequest
deriving (Show, Generic)
newAgentTag = "new_agent"
newJobTag = "new_job"
jobRequestTag = "job_request"
instance FromJSON SomeObj where
parseJSON (Object v) =
let -- create multiple parsers.
parseAgent = AnAgent <$> (v .: newAgentTag)
parseJob = AJob <$> (v .: newJobTag)
parseJobRequest = AJobRequest <$> (v .: jobRequestTag)
in -- Use one of the collection of parsers.
parseAgent <|> parseJob <|> parseJobRequest
parseJSON _ = mzero
instance ToJSON SomeObj where
toJSON (AnAgent agent) = object [newAgentTag .= agent]
toJSON (AJob job) = object [newJobTag .= job]
toJSON (AJobRequest jobRequest) = object [jobRequestTag .= jobRequest]
jsonFile :: FilePath
jsonFile = "sample-input.json"
-- Read the local copy of the JSON file.
getJSON :: IO B.ByteString
getJSON = B.readFile jsonFile
main :: IO ()
main = do
-- Get JSON data and decode it
d <- (eitherDecode <$> getJSON) :: IO (Either String [SomeObj])
-- If d is Left, the JSON was malformed.
-- In that case, we report the error.
-- Otherwise, we perform the operation of
-- our choice. In this case, just print it.
case d of
Left err -> putStrLn err
Right ps -> do
print ps
-- convert back to JSON.
let j2 = encode ps --
print j2
-- decode the newly converted JSON
let d2 = eitherDecode j2 :: Either String [SomeObj]
case d2 of
Left err -> putStrLn err
Right ps2 -> do
print ps2