Elm-使用动态键解码Json

Elm-使用动态键解码Json,json,dictionary,dynamic,decode,elm,Json,Dictionary,Dynamic,Decode,Elm,我想解码一个Json文件,如下所示: { 'result': [ {'id': 1, 'model': 'online', 'app_label': 'some_app_users'}, {'id': 2, 'model': 'rank', 'app_label': 'some_app_users'}, ]} { 'result': [ {'id': 1, 'name': 'Tom', 'skills': {'key': 'value', ...}, {'key':

我想解码一个Json文件,如下所示:

{ 'result': [
    {'id': 1, 'model': 'online', 'app_label': 'some_app_users'}, 
    {'id': 2, 'model': 'rank', 'app_label': 'some_app_users'}, 
]}
{ 'result': [
    {'id': 1, 'name': 'Tom', 'skills': {'key': 'value', ...}, {'key': 'value', ...}},
    {'id': 1, 'name': 'Bob', 'skills': {'key': 'value', ...}, {'key': 'value', ...}},
]}
Http.send GotTableContent (Http.get url tableContentDecoder)
或者像这样:

{ 'result': [
    {'id': 1, 'model': 'online', 'app_label': 'some_app_users'}, 
    {'id': 2, 'model': 'rank', 'app_label': 'some_app_users'}, 
]}
{ 'result': [
    {'id': 1, 'name': 'Tom', 'skills': {'key': 'value', ...}, {'key': 'value', ...}},
    {'id': 1, 'name': 'Bob', 'skills': {'key': 'value', ...}, {'key': 'value', ...}},
]}
Http.send GotTableContent (Http.get url tableContentDecoder)
基本上,
result
下的内容是具有相同键的dict列表-,但我事先不知道这些键,也不知道它们的值类型(int、string、dict等)

目标是显示数据库表内容;Json包含SQL查询的结果

我的解码器如下所示(未编译):

我是这样使用它的:

{ 'result': [
    {'id': 1, 'model': 'online', 'app_label': 'some_app_users'}, 
    {'id': 2, 'model': 'rank', 'app_label': 'some_app_users'}, 
]}
{ 'result': [
    {'id': 1, 'name': 'Tom', 'skills': {'key': 'value', ...}, {'key': 'value', ...}},
    {'id': 1, 'name': 'Bob', 'skills': {'key': 'value', ...}, {'key': 'value', ...}},
]}
Http.send GotTableContent (Http.get url tableContentDecoder)
我得到了一个错误:

函数
list
希望参数为: 解码器(Dict.Dict字符串a)

但事实是: 解码.解码器a->解码.解码器(Dict.Dict字符串a)


使用dict解码器的正确语法是什么?这样行吗?我找不到任何通用Elm解码器…

解码。list
是一个函数,它接受类型为
解码器a
的值,并返回类型为
解码器(列表a)
的值<代码>解码。dict也是一个函数,它采用
解码器a
类型的值,返回
解码器(dict字符串a)
的解码器。这告诉我们两件事:

  • 我们需要先将解码器值传递给
    Decode.dict
    ,然后再将其传递给
    decoder.list
  • Dict可能不适合您的用例,因为Dict只能在两个固定类型之间映射,并且不支持嵌套值,如
    'skills':{'key':'value',…}
Elm不提供通用解码器。其动机与Elm对“无运行时错误”的保证有关。在处理外部世界时,Elm需要保护其运行时不受外部故障、错误等的影响。Elm实现这一点的主要机制是类型。Elm只允许正确描述的数据进入,这样可以消除通用解码器可能引入的错误


由于您的主要目标是显示内容,类似于
Dict String
的方法可能会起作用,但这取决于数据嵌套的深度。您可以通过对代码稍加修改来实现这一点:
Decode.at[“result”]我不知道如何让
Decode.dict
正常工作,因此我更改了Json并拆分了列和结果:

data={
    'columns': [column.name for column in cursor.description],
    'results': [[str(column) for column in record] for record in cursor.fetchall()]
}
我还必须将所有结果转换为字符串以使其变得简单。例如,Json将有
“id”:“1”

通过这种方式完成Json,Elm代码非常简单:

type alias QueryResult =
    { columns : List String, results : List (List String) }

tableContentDecoder : Decode.Decoder QueryResult
tableContentDecoder =
    Decode.map2
        QueryResult
        (Decode.field "columns" (Decode.list Decode.string))
        (Decode.field "results" (Decode.list (Decode.list Decode.string)))

谢谢你,泰勒。我理解Elm解码器背后的原因。我已经将它用于预定义的负载,但我这里的问题实际上是关于动态负载(显示随机表的内容)。我尝试了
Decode.at[“result”]我找到了一种方法-非常接近您的解决方案。稍后将更新我的问题,提供更多详细信息。