我是elixir的新手,我想解析一个json文件。其中一部分是对象的问题答案数组。 [ { “ questionId”:1, “ question”:“信息:个人信息:名”, “ answer”:“ Joe” }, { “ questionId”:3, “ question”:“信息:个人信息:姓氏”, “ answer”:“ Smith” }, ... ]
我知道我想要什么QuestionId,我将为1 =名字,2 =姓氏制作一个地图。
但是目前我正在执行以下操作以将数据放入结构中。
defmodule Student do
defstruct first_name: nil, last_name: nil, student_number: nil
defguard is_first_name(id) when id == 1
defguard is_last_name(id) when id == 3
defguard is_student_number(id) when id == 7
end
defmodule AFMC do
import Student
@moduledoc """
Documentation for AFMC.
"""
@doc """
Hello world.
## Examples
iex> AFMC.hello
:world
"""
def main do
get_json()
|> get_outgoing_applications
end
def get_json do
with {:ok, body} <- File.read("./lib/afmc_import.txt"),
{:ok,body} <- Poison.Parser.parse(body), do: {:ok,body}
end
def get_outgoing_applications(map) do
{:ok,body} = map
out_application = get_in(body,["outgoingApplications"])
Enum.at(out_application,0)
|> get_in(["answers"])
|> get_person
end
def get_person(answers) do
student = Enum.reduce(answers,%Student{},fn(answer,acc) ->
if Student.is_first_name(answer["questionId"]) do
acc = %{acc | first_name: answer["answer"]}
end
if Student.is_last_name(answer["questionId"]) do
acc = %{acc | last_name: answer["answer"]}
end
if Student.is_student_number(answer["questionId"]) do
acc = %{acc | student_number: answer["answer"]}
end
acc
end)
IO.inspect "test"
s
end
end
我想知道有什么更好的方法来执行get_person而不必执行if语句。如果我知道我将映射1到对象数组中的questionId 1。 然后,数据将保存到数据库中。
谢谢
答案 0 :(得分:3)
我将存储id到字段名称的映射。这样,在reduce中就不需要任何if
。某些模式匹配也将使其不必要执行answer["questionId"]
等。
defmodule Student do
defstruct first_name: nil, last_name: nil, student_number: nil
@fields %{
1 => :first_name,
3 => :last_name,
7 => :student_number
}
def parse(answers) do
Enum.reduce(answers, %Student{}, fn %{"questionId" => id, "answer" => answer}, acc ->
%{acc | @fields[id] => answer}
end)
end
end
IO.inspect(
Student.parse([
%{"questionId" => 1, "question" => "", "answer" => "Joe"},
%{"questionId" => 3, "question" => "", "answer" => "Smith"},
%{"questionId" => 7, "question" => "", "answer" => "123"}
])
)
输出:
%Student{first_name: "Joe", last_name: "Smith", student_number: "123"}
编辑:要跳过地图中不存在的ID,请更改:
%{acc | @fields[id] => answer}
收件人:
if field = @fields[id], do: %{acc | field => answer}, else: acc