4

我已经使用 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)

但是这段代码给出了一些与访问相关的错误。

4

3 回答 3

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"}
# ]

在这里,我们对映射器中的值使用就地模式匹配来简化匹配器本身的代码,并使其在输入错误的情况下不易出错。

于 2017-11-17T08:23:50.730 回答
2

三件事:

  1. 你有一张地图,所以Enum.map会给你一个键和值的元组。您只需要此处的值,因此请执行以下操作:

    fn {_, item} ->
    
  2. 地图中的键是字符串。点语法仅适用于原子键。你需要做:

    item["attributes"]
    

    代替

    item.attributes
    

    其他键也类似。

  3. 你的价格是一个字符串。您需要先将其转换为浮点数,然后才能将其相乘。你可以这样做使用String.trim_leadingand 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"}]
于 2017-11-17T08:21:24.230 回答
1

您会遇到访问错误,因为您只能使用thing.property语法 ifproperty是一个原子并且在您的 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)
于 2018-02-10T05:40:41.753 回答