我使用Posion.decode解析了以下JSON!
json = %{"color-Black|size:10" =>
%{"attributes" => %{"color" => "Black","size" => "11"},
"isAvailable" => true,
"pricing" => %{"standard" => "$415.00", "sale" => 415}},
"color|size-EU:9.5" =>
%{"attributes" => %{"color" => "Black","size" => "11"},
"isAvailable" => true,
"pricing" => %{"standard" => "$415.00", "sale" => 415}}}
我想映射这个,并且我无法获取JSON元素,因为节点元素中的文本发生了变化。 到目前为止,我已经尝试过了。
Enum.map(json , fn(item) ->
%{
color: item.attributes["color"],
size: item.attributes["size"],
price: item.pricing["standard"] * 100,
isAvailable: item.isAvailable
}
end)
但是这段代码提供了一些与访问相关的错误。
答案 0 :(得分:4)
在映射地图时,迭代的键值对作为元组{key, value}
来到映射器:
Enum.map(json, fn {_, %{"attributes" => attributes,
"isAvailable" => isAvailable,
"pricing" => pricing}} ->
%{
color: attributes["color"],
size: attributes["size"],
price: pricing["standard"],
isAvailable: isAvailable
}
end)
#⇒ [
# %{color: "Black", isAvailable: true, price: "$415.00", size: "11"},
# %{color: "Black", isAvailable: true, price: "$415.00", size: "11"}
# ]
这里我们使用mapper中的值进行原位模式匹配,以简化匹配器本身的代码,并在输入错误的情况下减少错误。
答案 1 :(得分:2)
三件事:
你有一张地图,所以Enum.map
会给你一个关键和价值元组。你只想要这里的值,所以:
fn {_, item} ->
地图中的键是字符串。点语法仅适用于原子键。你需要这样做:
item["attributes"]
而不是
item.attributes
和其他键类似。
您的价格是一个字符串。您需要先将其转换为Float才能将其相乘。你可以使用String.trim_leading
和String.to_float
:
iex(1)> "$123.45" |> String.trim_leading("$") |> String.to_float
123.45
Enum.map(json, fn {_, item} ->
%{
color: item["attributes"]["color"],
size: item["attributes"]["size"],
price: item["pricing"]["standard"] |> String.trim_leading("$") |> String.to_float |> Kernel.*(100),
isAvailable: item["isAvailable"]
}
end)
|> IO.inspect
输出:
[%{color: "Black", isAvailable: true, price: 4.15e4, size: "11"},
%{color: "Black", isAvailable: true, price: 4.15e4, size: "11"}]
答案 2 :(得分:0)
您遇到访问错误,因为如果thing.property
是原子,您只能使用property
语法,而在json地图中,键是字符串。
使这更容易的一件事是Poison.decode
可以使用keys: :atoms
的第二个参数来返回带有原子键的地图。使用这里的内容,这将解决问题:
json_atoms = Poison.encode!(json) |> Poison.decode!(keys: :atoms)
convert_price = fn x ->
String.trim_leading(x, "$")
|> String.to_float
|> &(&1 * 100)
|> trunc
end
Enum.map(json_atoms, fn {_k,v} -> %{
color: v.attributes.color,
size: v.attributes.size,
price: convert_price.(v.pricing.standard),
isAvailable: v.isAvailable
} end)