创建一个未命名的对象以在JSON中序列化

oo7oh9g9  于 5个月前  发布在  其他
关注(0)|答案(1)|浏览(63)

我的函数将接受一个DataFrame并创建一组嵌套的Dict来表示一系列赠款。

function getgrants(Grantrows)
    if nrow(Grantrows)==0
        return nothing
    end
    Grants = Dict()
    let j = 0
        for GCSGrants in eachrow(Grantrows)
            j += 1
            Grants[j] = Dict(
                "GrantID" => GCSGrants.Grant_ID,
                "GrantDate" => GCSGrants.Grant_Date,
                "GrantAmount" => GCSGrants.Grant_Amount,
                "GrantTitle" => GCSGrants.Grant_Title,
                "GrantDistributor" => GCSGrants.Grant_Distributor,
            )
        end
    end
    return Grants
end

字符串
Grants本身嵌套在一个更大的Dict层次结构中,我最终使用它来创建一个json文件。

"Grants": {
   "1": {
       "GrantTitle": "Recipient 1",
       "GrantDate": "2022-03-16",
       "GrantAmount": 600000,
       "GrantDistributor": "Distributor 1",
       "GrantID": "ID789"
   },
   "2": {
       "GrantTitle": "Recipient 2",
       "GrantDate": "2020-09-02",
       "GrantAmount": 250000,
       "GrantDistributor": "Distributor 2",
       "GrantID": "ID456"
   },
   "3": {
       "GrantTitle": "Recipient 3",
       "GrantDate": "2020-06-25",
       "GrantAmount": 448770,
       "GrantDistributor": "Distributor 3",
       "GrantID": "ID123"
   }
}


枚举赠款是不必要的。我想只使用一系列未命名的对象。有没有简单的方法来做到这一点?

4xy9mtcn

4xy9mtcn1#

听起来你想要一个对象的JSON数组,而不是一个对象的对象。要做到这一点,在你的例子中将Grants设置为Vector{Dict}而不是Dict{Dict}。这个简化的例子动态地按行构建输出向量:

using DataFrames

function to_array_of_obj(df)
    output = Vector{Dict}()
    for row in eachrow(df)
        # you can filter out whatever keys you want for your needs here;
        # this just takes them all
        push!(output, Dict(names(row) .=> values(row))
    end
    return output
end

data = DataFrame(A=[1,2,3], B=["x", "y", "z"])

to_array_of_obj(data)
# 3-element Vector{Dict}:
#  Dict{String, Any}("B" => "x", "A" => 1)
#  Dict{String, Any}("B" => "y", "A" => 2)
#  Dict{String, Any}("B" => "z", "A" => 3)

字符串
此函数的输出将序列化为对象的JSON数组。例如,使用JSON3.jl

using JSON3

JSON3.pretty(to_array_of_obj(data))
# [
#     {
#         "B": "x",
#         "A": 1
#     },
#     {
#         "B": "y",
#         "A": 2
#     },
#     {
#         "B": "z",
#         "A": 3
#     }
# ]


如果你不介意使用Symbols作为键而不是String作为键的Dicts,你可以在一行程序中编写所有内容,利用eachrow(df)作为NamedTuple对象迭代的事实,并按照the answer to another SO question从NamedTuple构建Dicts:

to_array_of_obj2(df) = map(row -> Dict(pairs(row)), eachrow(df))

to_array_of_obj2(df)
# 3-element Vector{Dict{Symbol, Any}}:
#  Dict(:A => 1, :B => "x")
#  Dict(:A => 2, :B => "y")
#  Dict(:A => 3, :B => "z")


JSON3会像上面的例子一样序列化它。

相关问题