如何使用单个“键值”从JSON对象中提取单个值?
Http服务器以以下JSON格式返回数据:如何使用单个“键值”从JSON对象中提取单个值?,json,haskell,Json,Haskell,Http服务器以以下JSON格式返回数据: { some_value: "fdsafsafdsafs" } 具有单个键和值的对象 我想以这种格式解析返回的数据,但我还不能。我不想为此创建特殊的数据。 相反,我希望解析或解构/模式匹配它,并获得某个_值的值 代码: 二, 三, 所有的尝试都是错误的 如何执行此操作?很可能在第三次尝试时,您没有从中使用Data.HashMap.Strict模块的查找。此外,还应启用重载字符串选项以使用具有文本类型的字符串文字。因此,您可以将其实现为: {-
{
some_value: "fdsafsafdsafs"
}
具有单个键和值的对象
我想以这种格式解析返回的数据,但我还不能。我不想为此创建特殊的数据。
相反,我希望解析或解构/模式匹配它,并获得某个_值的值
代码:
二,
三,
所有的尝试都是错误的
如何执行此操作?很可能在第三次尝试时,您没有从中使用Data.HashMap.Strict模块的查找。此外,还应启用重载字符串选项以使用具有文本类型的字符串文字。因此,您可以将其实现为:
{-# LANGUAGE OverloadedStrings #-}
import qualified Data.HashMap.Strict as HM
import qualified Data.ByteString as BS
import qualified Data.Text as T
import qualified Data.Aeson as Aeson
func1 :: IO (Either MyError BS.ByteString)
func1 = do
resp <- sendRequestAndReturnJsonBody
case Aeson.decode resp of
Just (Aeson.Object obj) -> case (HM.lookup "some_value" obj) of
Just (Aeson.String s) -> pure (Right s)
_ -> undefined
_ -> undefined
它有一个类型,即给定resp是一个ByteString,它将返回一个Applicative f=>f或一个Text,因此如果在您的情况下resp确实是一个值,它可以返回一个IO或MyError
对于包含一个元素的对象,我们可以使用扩展名,从而利用该扩展名在该HashMap的列表模式上进行模式匹配:
对于更多项目,这将不匹配。尝试对更多项执行此操作可能会失败,因为带有toList的项的顺序未指定,因此可能取决于实现细节。即使您说不想创建自定义数据类型,这仍然是获取所需的let some_pattern=结果语法的最直接方法。请注意,除了解析之外,不需要将数据类型用于任何其他用途。可以将其视为创建新图案的常用Aeson方法,您可以在其上匹配结果 您可以使用泛型定义数据类型,也可以编写自定义FromJSON实例,以避免名称空间中的某个值字段混乱:
是否可以执行类似于此的操作,让对象具有一些值,字符串s=resp。我试过了,但没有compile@Rubashka351:这会很奇怪,因为一个对象正在包装一个HashMap。对于单例对象,可以使用重载列表扩展。
case Aeson.decode resp of
Just (Aeson.Object obj) -> -- how to exctract "some_value" from "obj" now?
_ -> _
let (Aeson.Object ("some_value", String s)) = resp
-- [......]
case resp of
(Object obj) ->
case (lookup "some_value" obj) of
Just (String s) -> pure $ Right s
_ -> undefined
{-# LANGUAGE OverloadedStrings #-}
import qualified Data.HashMap.Strict as HM
import qualified Data.ByteString as BS
import qualified Data.Text as T
import qualified Data.Aeson as Aeson
func1 :: IO (Either MyError BS.ByteString)
func1 = do
resp <- sendRequestAndReturnJsonBody
case Aeson.decode resp of
Just (Aeson.Object obj) -> case (HM.lookup "some_value" obj) of
Just (Aeson.String s) -> pure (Right s)
_ -> undefined
_ -> undefined
f :: Applicative f => ByteString -> f (Either a Text)
f resp = case Aeson.decode resp of
Just (Aeson.Object obj) -> case (HM.lookup "some_value" obj) of
Just (Aeson.String s) -> pure (Right s)
_ -> undefined
_ -> undefined
{-# LANGUAGE OverloadedLists, OverloadedStrings #-}
import qualified Data.ByteString as BS
import qualified Data.Text as T
import qualified Data.Aeson as Aeson
func1 :: IO (Either MyError BS.ByteString)
func1 = do
resp <- sendRequestAndReturnJsonBody
case Aeson.decode resp of
Just (Aeson.Object [("some_value", Aeson.String s)]) -> pure (Right s)
_ -> undefined
{-# LANGUAGE OverloadedStrings #-}
import Data.ByteString (ByteString)
import Data.Aeson
newtype SomeValue = SomeValue String
instance FromJSON SomeValue where
parseJSON = withObject "SomeValue" $ \o -> SomeValue <$> o .: "some_value"
myjson :: ByteString
myjson = "{ \"some_value\": \"fdsafsafdsafs\" }"
main = do
case decodeStrict myjson of
Just (SomeValue v) -> print v
_ -> error "didn't work!"